TempleOSCD_150216.ISO

This commit is contained in:
Terry A. Davis authored and minexew committed 2018-09-08 21:46:15 +02:00
1 parent 64f679eeb9
commit 401601816c
531 files changed
+23341 -22071

No files matched your search

-721
View File
@@ -1,721 +0,0 @@
Bool BlkDevLock(CBlkDev *bdev)
{//Make this task have exclusive access to BlkDev.
BlkDevChk(bdev);
while (bdev->lock_fwding)
bdev=bdev->lock_fwding;
if (!Bt(&bdev->locked_flags,BDlf_LOCKED) || bdev->owning_task!=Fs) {
while (LBts(&bdev->locked_flags,BDlf_LOCKED))
Yield;
bdev->owning_task=Fs;
return TRUE;
} else
return FALSE;
}
Bool PrtLock(CPrt *p)
{//Make this task have exclusive access to Prt & BlkDev.
PrtChk(p);
BlkDevLock(p->bdev);
if (!Bt(&p->locked_flags,Plf_LOCKED) || p->owning_task!=Fs) {
while (LBts(&p->locked_flags,Plf_LOCKED))
Yield;
p->owning_task=Fs;
return TRUE;
} else
return FALSE;
}
Bool BlkDevUnlock(CBlkDev *bdev,Bool rst=FALSE)
{//Release exclusive lock on access to BlkDev.
BlkDevChk(bdev);
while (bdev->lock_fwding)
bdev=bdev->lock_fwding;
if (Bt(&bdev->locked_flags,BDlf_LOCKED) && bdev->owning_task==Fs) {
if (rst)
bdev->flags&=~(BDF_INITIALIZED|BDF_INIT_IN_PROGRESS);
bdev->owning_task=NULL;
LBtr(&bdev->locked_flags,BDlf_LOCKED);
Yield; //Prevent deadlock
return TRUE;
} else
return FALSE;
}
Bool PrtUnlock(CPrt *p,Bool rst=FALSE)
{//Release exclusive lock on access to Prt & BlkDev.
PrtChk(p);
if (Bt(&p->locked_flags,Plf_LOCKED) && p->owning_task==Fs) {
BlkDevUnlock(p->bdev,rst);
p->owning_task=NULL;
LBtr(&p->locked_flags,Plf_LOCKED);
Yield; //Prevent deadlock
return TRUE;
} else
return FALSE;
}
Bool BlkDevInit(CBlkDev *bdev)
{
CPrt *p=Drv2Prt(bdev->first_drv_let);
Bool old_preempt=Preempt(OFF),result=FALSE;
if (!LBts(&bdev->flags,BDf_INITIALIZED)) {
bdev->flags|=BDF_INIT_IN_PROGRESS;
switch(bdev->type) {
case BDT_RAM:
if (!bdev->RAM_dsk) {
bdev->RAM_dsk=AMAlloc((bdev->max_blk+1)<<BLK_SIZE_BITS);
bdev->max_blk=MSize(bdev->RAM_dsk)>>BLK_SIZE_BITS-1;
}
p->type=PT_REDSEA;
p->size=bdev->max_blk+1;
if (RedSeaFSDrvValidate(bdev->first_drv_let))
RedSeaFSPrtInit(p);
else
RedSeaFSFmt(bdev->first_drv_let);
result=TRUE;
break;
case BDT_ATA:
bdev->max_reads=128;
bdev->max_writes=1;
result=ATAInit(bdev);
break;
case BDT_ATAPI:
//0xFFFF*4 is too big for my taste
bdev->max_reads=0x800*4;
//max of maybe a quarter of disk cache
if (bdev->max_reads>dsk.cache_size/BLK_SIZE/4)
bdev->max_reads=dsk.cache_size/BLK_SIZE/4 & ~3;
if (bdev->max_reads<128)
bdev->max_reads=128;
bdev->max_writes=0xFFFF*4;
if (result=ATAInit(bdev))
p->size=bdev->max_blk+1;
break;
}
if (result && bdev->flags & BDF_READ_CACHE)
DskCacheInvalidate(p);
bdev->flags&=~BDF_INIT_IN_PROGRESS;
} else
result=TRUE;
Preempt(old_preempt);
return result;
}
U0 BlkDevsRelease()
{//When task dies, release all owned BlkDevs.
I64 i;
CBlkDev *bdev;
for (i=0;i<NUM_BLKDEVS;i++) {
bdev=&dsk.blkdevs[i];
if (bdev->owning_task==Fs && bdev->bd_signature==BD_SIGNATURE_VAL)
BlkDevUnlock(bdev,TRUE);
}
}
U0 PrtsRelease()
{//When task dies, release all owned Prts.
I64 i;
CPrt *p;
for (i=0;i<NUM_PRTS;i++) {
p=&dsk.prts[i];
if (p->owning_task==Fs && p->pt_signature==PRT_SIGNATURE_VAL)
PrtUnlock(p,TRUE);
}
}
CPrt *PrtMakeFree(U8 drv_let)
{//Make a slot free for a new partition, like during $LK,"Mount",A="MN:Mount"$().
//!!! drv_let is not a $LK,"remapped",A="MN:MapDrv"$ prt.
I64 i=ToUpper(drv_let)-'A';
CPrt *result;
if (!(0<=i<NUM_PRTS))
throw('Prt');
result=&dsk.prts[i];
MemSet(result,0,sizeof(CPrt));
result->drv_let='A'+i;
return result;
}
CPrt *PrtNextFree(U8 first_drv_let='C')
{//Locate free slot for new partition, like during $LK,"Mount",A="MN:Mount"$().
//!!! first_drv_let is not a $LK,"remapped",A="MN:MapDrv"$ prt.
I64 i=ToUpper(first_drv_let)-'A';
if (!(0<=i<NUM_PRTS))
throw('Prt');
do
if (dsk.prts[i].pt_signature!=PRT_SIGNATURE_VAL)
return PrtMakeFree(i+'A');
while (++i<NUM_PRTS);
throw('Prt');
return NULL; //never gets here
}
CBlkDev *BlkDevNextFree(U8 first_drv_let,I64 type)
{//Locate free slot for new BlkDev, like during $LK,"Mount",A="MN:Mount"$().
I64 i=0;
CBlkDev *result;
do {
result=&dsk.blkdevs[i];
if (result->bd_signature!=BD_SIGNATURE_VAL) {
MemSet(result,0,sizeof(CBlkDev));
result->first_drv_let=first_drv_let;
result->type=type;
if (type==BDT_ATAPI)
result->flags=BDF_REMOVABLE;
else
result->flags=0;
if (type!=BDT_RAM)
result->flags|=BDF_READ_CACHE;
if (type==BDT_ATAPI) {
result->blk_size=CD_BLK_SIZE;
result->flags|=BDF_READ_ONLY;
} else
result->blk_size=BLK_SIZE;
result->max_blk=0xEFFFFFFF;
return result;
}
} while (++i<NUM_BLKDEVS);
throw('BlkDev');
return NULL; //never gets here
}
U0 MapBufAlloc(CPrt *p,I64 num_blks)
{
PrtChk(p);
Free(p->cur_map_blk);
Free(p->buffered_map_dirty_bits);
p->num_buffered_map_blks=num_blks;
p->cur_map_blk=AMAlloc(num_blks<<BLK_SIZE_BITS);
p->buffered_map_dirty_bits=ACAlloc((num_blks+7)>>3);
p->cur_map_blk_num=0;
RBlks(p,p->cur_map_blk,p->map1,p->num_buffered_map_blks);
}
U0 CleanMAPBuf(CPrt *p,I64 MAP_select=-1)
{
I64 i;
if ((MAP_select==-1 || !MAP_select) && p->map1!=p->map2)
for (i=0;i<p->num_buffered_map_blks;i++)
if (Bt(p->buffered_map_dirty_bits,i))
WBlks(p,p->cur_map_blk(I64)+i<<BLK_SIZE_BITS,p->map1+i+p->cur_map_blk_num,1);
if (MAP_select==-1 || MAP_select==1 || p->map1==p->map2)
for (i=0;i<p->num_buffered_map_blks;i++)
if (LBtr(p->buffered_map_dirty_bits,i))
WBlks(p,p->cur_map_blk(I64)+i<<BLK_SIZE_BITS,p->map2+i+p->cur_map_blk_num,1);
}
U0 SetFSBuf(CPrt *p,I64 c,I64 map_select=-1)
{
I64 MAP_blk_num;
if (c==INVALID_CLUSTER)
throw('Prt');
if (p->type==PT_FAT32)
MAP_blk_num=c>>(BLK_SIZE_BITS-2);
else
MAP_blk_num=c>>(BLK_SIZE_BITS+3);
if (MAP_blk_num!=p->cur_map_blk_num) {
CleanMAPBuf(p,map_select);
p->cur_map_blk_num=MAP_blk_num;
if (map_select==-1 || !map_select)
RBlks(p,p->cur_map_blk,p->map1+p->cur_map_blk_num,1);
else
RBlks(p,p->cur_map_blk,p->map2+p->cur_map_blk_num,1);
}
}
#define ZERO_BUF_SIZE 2048
U0 WZeroBlks(CPrt *p,I64 blk,I64 cnt)
{//Fill blk cnt with zeros in Prt.
I64 n;
U8 *z=CAlloc(ZERO_BUF_SIZE<<BLK_SIZE_BITS);
Bool show_progress;
if (cnt>ZERO_BUF_SIZE && p->bdev->type!=BDT_RAM) {
progress1=0; progress1_max=cnt;
StrCpy(progress1_desc,"Zeroing");
show_progress=TRUE;
} else
show_progress=FALSE;
while (cnt>0) {
n=cnt;
if (n>ZERO_BUF_SIZE)
n=ZERO_BUF_SIZE;
WBlks(p,z,blk,n);
blk+=n;
cnt-=n;
if (show_progress)
progress1+=n;
Yield; //Prevent locking
}
Free(z);
if (show_progress) {
*progress1_desc=0;
progress1=progress1_max=0;
}
}
Bool SetDrvType(U8 drv_let,I64 type=PT_REDSEA)
{//Very dangerous
I64 i,j,ext_base,prt_num,offset,cur_type;
CMasterBoot mbr;
CBlkDev *bdev=Drv2BlkDev(drv_let);
prt_num=bdev->first_drv_let-'A';
switch (bdev->type) {
case BDT_ATA:
offset=0;
ext_base=INVALID_CLUSTER;
while (TRUE) {
ATAReadBlks(bdev,&mbr,offset,1);
j=-1;
for (i=0;i<4;i++) {
cur_type=mbr.p[i].type;
if (cur_type) {
if (cur_type==5 || cur_type==15)
j=i;
else {
if (prt_num+'A'==ToUpper(drv_let)) {
switch (type) {
case PT_REDSEA:
mbr.p[i].type=MBR_PT_REDSEA;
break;
case PT_FAT32:
mbr.p[i].type=MBR_PT_FAT32a;
break;
default:
Dbg;
}
mbr.p[i].active=0x80;
ATAWriteBlks(bdev,&mbr,offset,1);
return TRUE;
}
prt_num++;
}
}
}
if (j<0)
break;
if (!mbr.p[j].offset)
break;
if (ext_base==INVALID_CLUSTER) {
offset=mbr.p[j].offset;
ext_base=offset;
} else
offset=mbr.p[j].offset+ext_base;
}
break;
}
}
Bool RBlks(CPrt *p,U8 *buf, I64 blk, I64 cnt)
{//Read blk cnt from Prt to buf.
Bool result=TRUE,unlock;
CBlkDev *bdev=p->bdev;
if (cnt<=0) return TRUE;
PrtChk(p);
try {
unlock=PrtLock(p);
BlkDevInit(bdev);
if (p->offset && blk<p->offset || blk+cnt>p->offset+p->size)
throw('Prt');
if (bdev->flags & BDF_READ_CACHE)
RCache(p,&buf,&blk,&cnt);
if (cnt>0) {
switch (bdev->type) {
case BDT_RAM:
MemCpy(buf,bdev->RAM_dsk+blk<<BLK_SIZE_BITS,cnt<<BLK_SIZE_BITS);
break;
case BDT_ATA:
case BDT_ATAPI:
result=ATARBlks(p,buf,blk,cnt);
break;
}
bdev->last_time=tS;
if (bdev->flags & BDF_READ_CACHE)
DskCacheAdd(p,buf,blk,cnt);
}
if (unlock)
PrtUnlock(p);
} catch
if (unlock)
PrtUnlock(p);
return result;
}
Bool WBlks(CPrt *p,U8 *buf, I64 blk, I64 cnt)
{//Write blk cnt from buf to Prt.
Bool result=TRUE,unlock;
CBlkDev *bdev=p->bdev;
if (cnt<=0) return TRUE;
PrtChk(p);
try {
unlock=PrtLock(p);
BlkDevInit(bdev);
if (bdev->flags&BDF_READ_ONLY &&
!(bdev->flags & BDF_READ_ONLY_OVERRIDE))
throw('BlkDev');
if (p->offset && blk<p->offset || blk+cnt>p->offset+p->size)
throw('Prt');
if (cnt>0) {
switch (bdev->type) {
case BDT_RAM:
MemCpy(bdev->RAM_dsk+blk<<BLK_SIZE_BITS,buf,cnt<<BLK_SIZE_BITS);
break;
case BDT_ATA:
case BDT_ATAPI:
result=ATAWBlks(p,buf,blk,cnt);
break;
}
bdev->last_time=tS;
if (bdev->flags & BDF_READ_CACHE)
DskCacheAdd(p,buf,blk,cnt);
}
if (unlock)
PrtUnlock(p);
} catch
if (unlock)
PrtUnlock(p);
return result;
}
U0 DskCacheInvalidate(CPrt *p)
{//Needed for removable media. Called by $LK,"ChgDsk",A="MN:ChgDsk"$().
Bool unlock;
CBlkDev *bdev=p->bdev;
PrtChk(p);
try {
unlock=PrtLock(p);
BlkDevInit(bdev);
if (bdev->flags & BDF_READ_CACHE)
DskCacheInvalidate2(p);
if (p->type==PT_ISO9660) {
if (!(bdev->flags & BDF_READ_ONLY_OVERRIDE))
ISOPrtInit(p,(32767/bdev->blk_size+1)*
bdev->blk_size>>BLK_SIZE_BITS);
}
if (unlock)
PrtUnlock(p);
} catch
if (unlock)
PrtUnlock(p);
}
U0 ChgDsk(U8 drv_let=0)
{//Change disk. (Needed for removable media.)
CPrt *p=Drv2Prt(drv_let);
CBlkDev *bdev=p->bdev;
Bool old_preempt=Preempt(OFF);
if (!(bdev->flags&BDF_INITIALIZED))
BlkDevInit(bdev);
else if (bdev->flags&BDF_REMOVABLE)
DskCacheInvalidate(p);
Drv(drv_let);
RedSeaFSFreeFreeLst(p);
Preempt(old_preempt);
}
U8 *DrvSerialNum(U8 drv_let=0)
{//20 bytes max.
CBlkDev *bdev=Drv2BlkDev(drv_let);
U16 *st,*result=NULL;
I64 i;
if (bdev->dev_id_record) {
st=CAlloc(20+1);
for (i=0;i<10;i++)
st[i]=EndianU16(bdev->dev_id_record[10+i]);
result=MStrUtil(st,SUF_REM_LEADING|SUF_REM_TRAILING);
Free(st);
}
return result;
}
U8 *DrvModelNum(U8 drv_let=0)
{//40 bytes max.
CBlkDev *bdev=Drv2BlkDev(drv_let);
U16 *st,*result=NULL;
I64 i;
if (bdev->dev_id_record) {
st=CAlloc(40+1);
for (i=0;i<20;i++)
st[i]=EndianU16(bdev->dev_id_record[27+i]);
result=MStrUtil(st,SUF_REM_LEADING|SUF_REM_TRAILING);
Free(st);
}
return result;
}
U0 PrtRep()
{//Partition report.
CPrt *p;
CBlkDev *bdev;
I64 i,drv_let;
U8 *st;
"\nDefined Partitions:\n\n";
for (i=0,p=dsk.prts;i<NUM_PRTS;i++,p++) {
if (p->pt_signature==PRT_SIGNATURE_VAL) {
bdev=p->bdev;
drv_let=Prt2Drv(p);
if (Bt(&p->type,PTf_DISABLE))
"$$RED$$X";
else if (drv_let==*sys_acct)
"$$GREEN$$:";
else
'' CH_SPACE;
"$$PURPLE$$%C %-8Z %-9Z %04X %04X %02X$$FG$$\n",
drv_let,p->type.u16[0],"ST_PRT_TYPES",
bdev->type,"ST_BLKDEV_TYPES",bdev->base0,bdev->base1,bdev->unit;
if (st=DrvModelNum(drv_let)) {
" $$CYAN$$Model# :%s$$FG$$\n",st;
Free(st);
}
if (st=DrvSerialNum(drv_let)) {
" $$CYAN$$Serial#:%s$$FG$$\n",st;
Free(st);
}
" %016X-%016X\n",
p->offset,p->offset+p->size-1;
p->offset,p->offset+p->size-1;
}
}
}
I64 ClusterNumNext(CPrt *p,I64 c,I64 cnt=1)
{//Return next cnt'th cluster in chain.
Bool unlock;
PrtChk(p);
if (cnt<=0) return c;
try {
unlock=PrtLock(p);
switch (p->type) {
case PT_ISO9660:
case PT_REDSEA:
c+=cnt;
break;
case PT_FAT32:
while (cnt-->0 && 0<c<0x0FFFFFF8) {
SetFSBuf(p,c);
c=p->cur_map_blk[c & (BLK_SIZE/4-1)];
}
if (!(0<c<0x0FFFFFF8))
c=INVALID_CLUSTER;
break;
default:
Dbg;
}
if (unlock)
PrtUnlock(p);
} catch
if (unlock)
PrtUnlock(p);
return c;
}
I64 Cluster2Blk(CPrt *p,I64 c)
{//Prt cluster num to blk num.
PrtChk(p);
return p->data+c*p->spc;
}
I64 RClustersBlks(CPrt *p,U8 *buf,I64 c,I64 blks)
{//Accepts blk count, so padding on last cluster is not read.
I64 i;
Bool unlock;
PrtChk(p);
if (blks<=0) return c;
try {
unlock=PrtLock(p);
switch (p->type) {
case PT_ISO9660:
case PT_REDSEA:
RBlks(p,buf,p->data+c*p->spc,blks);
c+=(blks+p->spc-1)/p->spc;
break;
case PT_FAT32:
while (blks && 0<c<0x0FFFFFF8) {
i=blks;
if (i>p->spc)
i=p->spc;
RBlks(p,buf,p->data+c*p->spc,i);
buf+=i<<BLK_SIZE_BITS;
c=ClusterNumNext(p,c,1);
blks-=i;
}
if (blks)
Dbg;
break;
default:
Dbg;
}
if (unlock)
PrtUnlock(p);
} catch
if (unlock)
PrtUnlock(p);
return c;
}
I64 RClusters(CPrt *p,U8 *buf,I64 c,I64 cnt)
{//Read cluster cnt from Prt to buf.
return RClustersBlks(p,buf,c,cnt*p->spc);
}
Bool CFileNameTo(U8 *dst,U8 *src)
{
MemSet(dst,0,CDIR_FILENAME_LEN);
if (!FileNameChk(src))
return FALSE;
StrCpy(dst,src);
return TRUE;
}
I64 Name2DirCluster(CPrt *p,U8 *dirname)
{
Bool cont=TRUE,unlock;
I64 cur_dir_cluster;
CDirEntry de;
U8 *buf=StrNew(dirname),*buf2=StrNew(dirname);
PrtChk(p);
try {
unlock=PrtLock(p);
cur_dir_cluster=p->root_cluster;
while (*buf && cont) {
StrFirstRem(buf,"/",buf2);
if (*buf2) {
switch (p->type) {
case PT_REDSEA:
cont=RedSeaFSFileFind(p,cur_dir_cluster,buf2,&de,FUF_JUST_DIRS);
break;
case PT_FAT32:
cont=FAT32FileFind(p,cur_dir_cluster,buf2,&de,FUF_JUST_DIRS);
break;
case PT_ISO9660:
cont=ISO1FileFind(p,cur_dir_cluster,buf2,&de,FUF_JUST_DIRS);
break;
default:
Dbg;
}
cur_dir_cluster=de.cluster;
}
}
if (!cont) {
"%s ",dirname;
PrintErr("File not found.\n");
cur_dir_cluster=0;
}
if (unlock)
PrtUnlock(p);
} catch
if (unlock)
PrtUnlock(p);
Free(buf);
Free(buf2);
return cur_dir_cluster;
}
I64 Name2ParentDirCluster(CPrt *p,U8 *dirname)
{
Bool cont=TRUE,unlock;
I64 cur_dir_cluster,cur_dir_cluster2;
CDirEntry de;
U8 *buf=StrNew(dirname),*buf2=StrNew(dirname);
PrtChk(p);
try {
unlock=PrtLock(p);
cur_dir_cluster=cur_dir_cluster2=p->root_cluster;
while (*buf && cont) {
cur_dir_cluster2=cur_dir_cluster;
StrFirstRem(buf,"/",buf2);
if (*buf2) {
switch (p->type) {
case PT_REDSEA:
cont=RedSeaFSFileFind(p,cur_dir_cluster,buf2,&de,FUF_JUST_DIRS);
break;
case PT_FAT32:
cont=FAT32FileFind(p,cur_dir_cluster,buf2,&de,FUF_JUST_DIRS);
break;
case PT_ISO9660:
cont=ISO1FileFind(p,cur_dir_cluster,buf2,&de,FUF_JUST_DIRS);
break;
default:
Dbg;
}
cur_dir_cluster=de.cluster;
}
}
if (!cont) {
"%s ",dirname;
PrintErr("File not found.\n");
cur_dir_cluster2=0;
}
if (unlock)
PrtUnlock(p);
} catch
if (unlock)
PrtUnlock(p);
Free(buf);
Free(buf2);
return cur_dir_cluster2;
}
I64 WClustersBlks(CPrt *p,U8 *buf,I64 c,I64 blks)
{//Accepts blk count, so padding on last cluster is not written.
I64 i;
Bool unlock;
PrtChk(p);
if (blks<=0) return c;
try {
unlock=PrtLock(p);
switch (p->type) {
case PT_REDSEA:
WBlks(p,buf,p->data+c*p->spc,blks);
c=0;
break;
case PT_FAT32:
while (blks) {
if (!(0<c<0x0FFFFFF8))
Dbg;
i=blks;
if (i>p->spc)
i=p->spc;
WBlks(p,buf,p->data+c*p->spc,i);
buf+=i<<BLK_SIZE_BITS;
c=ClusterNumNext(p,c);
blks-=i;
}
break;
default:
Dbg;
}
if (unlock)
PrtUnlock(p);
} catch
if (unlock)
PrtUnlock(p);
return c;
}
I64 WClusters(CPrt *p,U8 *buf,I64 c,I64 cnt)
{//Write cluster cnt from buf to Prt.
return WClustersBlks(p,buf,c,cnt*p->spc);
}
I64 ClustersAlloc(CPrt *p,I64 c=0,I64 cnt=1,Bool contiguous=FALSE)
{//Alloc cluster cnt into chain.
//c=0 means first cluster in chain
PrtChk(p);
if (cnt<=0) return c;
switch (p->type) {
case PT_REDSEA:
return RedSeaFSAllocClusters(p,cnt);
case PT_FAT32:
if (contiguous) {
if (c) throw('File');
return FAT32AllocContiguousClusters(p,cnt);
} else
return FAT32AllocClusters(p,c,cnt);
default:
Dbg;
}
}
+731
View File
@@ -0,0 +1,731 @@
Bool BlkDevLock(CBlkDev *bd)
{//Make this task have exclusive access to BlkDev.
BlkDevChk(bd);
while (bd->lock_fwding)
bd=bd->lock_fwding; //If two blkdevs on same controller, use just one lock
if (!Bt(&bd->locked_flags,BDlf_LOCKED) || bd->owning_task!=Fs) {
while (LBts(&bd->locked_flags,BDlf_LOCKED))
Yield;
bd->owning_task=Fs;
return TRUE;
} else
return FALSE;
}
Bool DrvLock(CDrv *dv)
{//Make this task have exclusive access to drv & BlkDev.
DrvChk(dv);
BlkDevLock(dv->bd);
if (!Bt(&dv->locked_flags,DVlf_LOCKED) || dv->owning_task!=Fs) {
while (LBts(&dv->locked_flags,DVlf_LOCKED))
Yield;
dv->owning_task=Fs;
return TRUE;
} else
return FALSE;
}
Bool BlkDevUnlock(CBlkDev *bd,Bool rst=FALSE)
{//Release exclusive lock on access to BlkDev.
BlkDevChk(bd);
while (bd->lock_fwding)
bd=bd->lock_fwding; //If two blkdevs on same controller, use just one lock
if (Bt(&bd->locked_flags,BDlf_LOCKED) && bd->owning_task==Fs) {
if (rst)
bd->flags&=~(BDF_INITIALIZED|BDF_INIT_IN_PROGRESS);
bd->owning_task=NULL;
LBtr(&bd->locked_flags,BDlf_LOCKED);
Yield; //Prevent deadlock
return TRUE;
} else
return FALSE;
}
Bool DrvUnlock(CDrv *dv,Bool rst=FALSE)
{//Release exclusive lock on access to drv & BlkDev.
DrvChk(dv);
if (Bt(&dv->locked_flags,DVlf_LOCKED) && dv->owning_task==Fs) {
BlkDevUnlock(dv->bd,rst);
dv->owning_task=NULL;
LBtr(&dv->locked_flags,DVlf_LOCKED);
Yield; //Prevent deadlock
return TRUE;
} else
return FALSE;
}
Bool BlkDevInit(CBlkDev *bd)
{
CDrv *dv=Let2Drv(bd->first_drv_let);
Bool old_preempt=Preempt(OFF),result=FALSE;
if (!LBts(&bd->flags,BDf_INITIALIZED)) {
bd->flags|=BDF_INIT_IN_PROGRESS;
switch(bd->type) {
case BDT_RAM:
if (!bd->RAM_dsk) {
bd->RAM_dsk=AMAlloc((bd->max_blk+1)<<BLK_SIZE_BITS);
bd->max_blk=MSize(bd->RAM_dsk)>>BLK_SIZE_BITS-1;
}
dv->type=DVT_REDSEA;
dv->size=bd->max_blk+1;
if (RedSeaDrvValidate(bd->first_drv_let))
RedSeaDrvInit(dv);
else
RedSeaFmt(bd->first_drv_let);
result=TRUE;
break;
case BDT_ATA:
bd->max_reads=128;
bd->max_writes=1;
result=ATAInit(bd);
break;
case BDT_ATAPI:
//0xFFFF*4 is too big for my taste
bd->max_reads=0x800*4;
//max of maybe a quarter of disk cache
if (bd->max_reads>dsk.cache_size/BLK_SIZE/4)
bd->max_reads=dsk.cache_size/BLK_SIZE/4 & ~3;
if (bd->max_reads<128)
bd->max_reads=128;
bd->max_writes=0xFFFF*4;
if (result=ATAInit(bd))
dv->size=bd->max_blk+1;
break;
}
if (result && bd->flags & BDF_READ_CACHE)
DskCacheInvalidate(dv);
bd->flags&=~BDF_INIT_IN_PROGRESS;
} else
result=TRUE;
Preempt(old_preempt);
return result;
}
U0 BlkDevsRelease()
{//When task dies, release all owned BlkDevs.
I64 i;
CBlkDev *bd;
for (i=0;i<NUM_BLKDEVS;i++) {
bd=&dsk.blkdevs[i];
if (bd->owning_task==Fs && bd->bd_signature==BD_SIGNATURE_VAL)
BlkDevUnlock(bd,TRUE);
}
}
U0 DrvsRelease()
{//When task dies, release all owned drvs.
I64 i;
CDrv *dv;
for (i=0;i<NUM_DRVS;i++) {
dv=&dsk.drvs[i];
if (dv->owning_task==Fs && dv->dv_signature==DRV_SIGNATURE_VAL)
DrvUnlock(dv,TRUE);
}
}
CDrv *DrvMakeFree(U8 drv_let)
{//Make a slot free for a new drv, like during $LK,"Mount",A="MN:Mount"$().
//!!! drv_let is not a $LK,"remapped",A="MN:MapDrv"$ drv.
I64 i=ToUpper(drv_let)-'A';
CDrv *result;
if (!(0<=i<NUM_DRVS))
throw('Drv');
result=&dsk.drvs[i];
MemSet(result,0,sizeof(CDrv));
result->drv_let='A'+i;
return result;
}
CDrv *DrvNextFree(U8 first_drv_let='C')
{//Locate free slot for new drv, like during $LK,"Mount",A="MN:Mount"$().
//!!! first_drv_let is not a $LK,"remapped",A="MN:MapDrv"$ drv.
I64 i=ToUpper(first_drv_let)-'A';
if (!(0<=i<NUM_DRVS))
throw('Drv');
do
if (dsk.drvs[i].dv_signature!=DRV_SIGNATURE_VAL)
return DrvMakeFree(i+'A');
while (++i<NUM_DRVS);
throw('Drv');
return NULL; //never gets here
}
CBlkDev *BlkDevNextFree(U8 first_drv_let,I64 type)
{//Locate free slot for new BlkDev, like during $LK,"Mount",A="MN:Mount"$().
I64 i=0;
CBlkDev *result;
do {
result=&dsk.blkdevs[i];
if (result->bd_signature!=BD_SIGNATURE_VAL) {
MemSet(result,0,sizeof(CBlkDev));
result->first_drv_let=first_drv_let;
result->type=type;
if (type==BDT_ATAPI)
result->flags=BDF_REMOVABLE;
else
result->flags=0;
if (type!=BDT_RAM)
result->flags|=BDF_READ_CACHE;
if (type==BDT_ATAPI) {
result->blk_size=CD_BLK_SIZE;
result->flags|=BDF_READ_ONLY;
} else
result->blk_size=BLK_SIZE;
result->max_blk=0xEFFFFFFF;
return result;
}
} while (++i<NUM_BLKDEVS);
throw('BlkDev');
return NULL; //never gets here
}
U0 DrvMapBlkAlloc(CDrv *dv)
{
DrvChk(dv);
Free(dv->cur_map_blk);
dv->cur_map_blk=AMAlloc(BLK_SIZE);
dv->cur_map_blk_num=0;
dv->map_blk_dirty=0;
RBlks(dv,dv->cur_map_blk,dv->map1,1);
}
U0 DrvMapBlkClean(CDrv *dv,I64 map_select=3)
{
if (dv->type==DVT_FAT32 || dv->type==DVT_REDSEA) {
if ((map_select==3 || !map_select) && dv->map1!=dv->map2 &&
Bt(&dv->map_blk_dirty,0))
WBlks(dv,dv->cur_map_blk(I64),dv->map1+dv->cur_map_blk_num,1);
if (map_select==3 || map_select==1 || dv->map1==dv->map2 &&
LBtr(&dv->map_blk_dirty,0))
WBlks(dv,dv->cur_map_blk(I64),dv->map2+dv->cur_map_blk_num,1);
}
}
U0 DrvMapBlkSet(CDrv *dv,I64 c,I64 map_select=3)
{
I64 map_blk_num;
if (c==INVALID_CLUSTER)
throw('Drv');
switch (dv->type) {
case DVT_FAT32:
map_blk_num=c>>(BLK_SIZE_BITS-2);
break;
case DVT_REDSEA:
map_blk_num=(c-dv->data_area)>>(BLK_SIZE_BITS+3);
break;
default:
throw('Drv');
}
if (map_blk_num!=dv->cur_map_blk_num) {
DrvMapBlkClean(dv,map_select);
dv->cur_map_blk_num=map_blk_num;
if (map_select==3 || !map_select)
RBlks(dv,dv->cur_map_blk,dv->map1+dv->cur_map_blk_num,1);
else
RBlks(dv,dv->cur_map_blk,dv->map2+dv->cur_map_blk_num,1);
}
}
#define ZERO_BUF_SIZE 2048
U0 WZeroBlks(CDrv *dv,I64 blk,I64 cnt)
{//Fill blk cnt with zeros in Drv.
I64 n;
U8 *z=CAlloc(ZERO_BUF_SIZE<<BLK_SIZE_BITS);
Bool show_progress;
if (cnt>ZERO_BUF_SIZE && dv->bd->type!=BDT_RAM) {
progress1=0; progress1_max=cnt;
StrCpy(progress1_desc,"Zeroing");
show_progress=TRUE;
} else
show_progress=FALSE;
while (cnt>0) {
n=cnt;
if (n>ZERO_BUF_SIZE)
n=ZERO_BUF_SIZE;
WBlks(dv,z,blk,n);
blk+=n;
cnt-=n;
if (show_progress)
progress1+=n;
Yield; //Prevent locking
}
Free(z);
if (show_progress) {
*progress1_desc=0;
progress1=progress1_max=0;
}
}
Bool DrvTypeSet(U8 drv_let,I64 type=DVT_REDSEA)
{//Very dangerous
I64 i,j,ext_base,drv_num,offset,cur_type;
CMasterBoot mbr;
CBlkDev *bd=Let2BlkDev(drv_let);
drv_num=bd->first_drv_let-'A';
switch (bd->type) {
case BDT_ATA:
offset=0;
ext_base=INVALID_CLUSTER;
while (TRUE) {
ATAReadBlks(bd,&mbr,offset,1);
j=-1;
for (i=0;i<4;i++) {
cur_type=mbr.p[i].type;
if (cur_type) {
if (cur_type==5 || cur_type==15)
j=i;
else {
if (drv_num+'A'==ToUpper(drv_let)) {
switch (type) {
case DVT_REDSEA:
mbr.p[i].type=MBR_PT_REDSEA;
break;
case DVT_FAT32:
mbr.p[i].type=MBR_PT_FAT32a;
break;
default:
throw('Drv');
}
mbr.p[i].active=0x80;
ATAWriteBlks(bd,&mbr,offset,1);
return TRUE;
}
drv_num++;
}
}
}
if (j<0)
break;
if (!mbr.p[j].offset)
break;
if (ext_base==INVALID_CLUSTER) {
offset=mbr.p[j].offset;
ext_base=offset;
} else
offset=mbr.p[j].offset+ext_base;
}
break;
}
}
Bool RBlks(CDrv *dv,U8 *buf, I64 blk, I64 cnt)
{//Read blk cnt from Drv to buf.
Bool result=TRUE,unlock;
CBlkDev *bd=dv->bd;
if (cnt<=0) return TRUE;
DrvChk(dv);
try {
unlock=DrvLock(dv);
BlkDevInit(bd);
if (dv->base_offset && blk<dv->base_offset || blk+cnt>dv->base_offset+dv->size)
throw('Drv');
if (bd->flags & BDF_READ_CACHE)
RCache(dv,&buf,&blk,&cnt);
if (cnt>0) {
switch (bd->type) {
case BDT_RAM:
MemCpy(buf,bd->RAM_dsk+blk<<BLK_SIZE_BITS,cnt<<BLK_SIZE_BITS);
break;
case BDT_ATA:
case BDT_ATAPI:
result=ATARBlks(dv,buf,blk,cnt);
break;
}
bd->last_time=tS;
if (bd->flags & BDF_READ_CACHE)
DskCacheAdd(dv,buf,blk,cnt);
}
if (unlock)
DrvUnlock(dv);
} catch
if (unlock)
DrvUnlock(dv);
return result;
}
Bool WBlks(CDrv *dv,U8 *buf, I64 blk, I64 cnt)
{//Write blk cnt from buf to Drv.
Bool result=TRUE,unlock;
CBlkDev *bd=dv->bd;
if (cnt<=0) return TRUE;
DrvChk(dv);
try {
unlock=DrvLock(dv);
BlkDevInit(bd);
if (bd->flags&BDF_READ_ONLY && !(bd->flags & BDF_READ_ONLY_OVERRIDE))
throw('BlkDev');
if (dv->base_offset && blk<dv->base_offset || blk+cnt>dv->base_offset+dv->size)
throw('Drv');
if (cnt>0) {
switch (bd->type) {
case BDT_RAM:
MemCpy(bd->RAM_dsk+blk<<BLK_SIZE_BITS,buf,cnt<<BLK_SIZE_BITS);
break;
case BDT_ATA:
case BDT_ATAPI:
result=ATAWBlks(dv,buf,blk,cnt);
break;
}
bd->last_time=tS;
if (bd->flags & BDF_READ_CACHE)
DskCacheAdd(dv,buf,blk,cnt);
}
if (unlock)
DrvUnlock(dv);
} catch
if (unlock)
DrvUnlock(dv);
return result;
}
U0 DskCacheInvalidate(CDrv *dv)
{//Needed for removable media. Called by $LK,"ChgDsk",A="MN:ChgDsk"$().
Bool unlock;
CBlkDev *bd=dv->bd;
DrvChk(dv);
try {
unlock=DrvLock(dv);
BlkDevInit(bd);
if (bd->flags & BDF_READ_CACHE)
DskCacheInvalidate2(dv);
if (dv->type==DVT_ISO9660 && !(bd->flags & BDF_READ_ONLY_OVERRIDE))
ISODrvInit(dv,(32767/bd->blk_size+1)*bd->blk_size>>BLK_SIZE_BITS);
if (unlock)
DrvUnlock(dv);
} catch
if (unlock)
DrvUnlock(dv);
}
U0 ChgDsk(U8 drv_let=0)
{//Change disk. (Needed for removable media.)
CDrv *dv=Let2Drv(drv_let);
CBlkDev *bd=dv->bd;
Bool old_preempt=Preempt(OFF);
if (!(bd->flags&BDF_INITIALIZED))
BlkDevInit(bd);
else if (bd->flags&BDF_REMOVABLE)
DskCacheInvalidate(dv);
Drv(drv_let);
RedSeaFreeFreeLst(dv);
Preempt(old_preempt);
}
U8 *DrvSerialNum(U8 drv_let=0)
{//20 bytes max.
CBlkDev *bd=Let2BlkDev(drv_let);
U16 *st,*result=NULL;
I64 i;
if (bd->dev_id_record) {
st=CAlloc(20+1);
for (i=0;i<10;i++)
st[i]=EndianU16(bd->dev_id_record[10+i]);
result=MStrUtil(st,SUF_REM_LEADING|SUF_REM_TRAILING);
Free(st);
}
return result;
}
U8 *DrvModelNum(U8 drv_let=0)
{//40 bytes max.
CBlkDev *bd=Let2BlkDev(drv_let);
U16 *st,*result=NULL;
I64 i;
if (bd->dev_id_record) {
st=CAlloc(40+1);
for (i=0;i<20;i++)
st[i]=EndianU16(bd->dev_id_record[27+i]);
result=MStrUtil(st,SUF_REM_LEADING|SUF_REM_TRAILING);
Free(st);
}
return result;
}
U0 DrvRep()
{//Drive report.
CDrv *dv;
CBlkDev *bd;
I64 i,drv_let;
U8 *st;
"\nDefined Drives:\n\n";
for (i=0,dv=dsk.drvs;i<NUM_DRVS;i++,dv++) {
if (dv->dv_signature==DRV_SIGNATURE_VAL) {
bd=dv->bd;
drv_let=Drv2Let(dv);
if (Bt(&dv->type,DVTf_DISABLE))
"$$RED$$X";
else if (drv_let==dsk.boot_drv_let)
"$$GREEN$$:";
else
'' CH_SPACE;
"$$PURPLE$$%C %-8Z %-9Z %04X %04X %02X$$FG$$\n",
drv_let,dv->type.u16[0],"ST_DRV_TYPES",
bd->type,"ST_BLKDEV_TYPES",bd->base0,bd->base1,bd->unit;
if (st=DrvModelNum(drv_let)) {
" $$CYAN$$Model# :%s$$FG$$\n",st;
Free(st);
}
if (st=DrvSerialNum(drv_let)) {
" $$CYAN$$Serial#:%s$$FG$$\n",st;
Free(st);
}
" %016X-%016X\n",
dv->base_offset,dv->base_offset+dv->size-1;
dv->base_offset,dv->base_offset+dv->size-1;
}
}
}
I64 ClusterNumNext(CDrv *dv,I64 c,I64 cnt=1)
{//Return next cnt'th cluster in chain.
Bool unlock;
DrvChk(dv);
if (cnt<=0) return c;
try {
unlock=DrvLock(dv);
switch (dv->type) {
case DVT_ISO9660:
case DVT_REDSEA:
c+=cnt;
break;
case DVT_FAT32:
while (cnt-->0 && 0<c<0x0FFFFFF8) {
DrvMapBlkSet(dv,c);
c=dv->cur_map_blk[c & (BLK_SIZE/4-1)];
}
if (!(0<c<0x0FFFFFF8))
c=INVALID_CLUSTER;
break;
default:
throw('Drv');
}
if (unlock)
DrvUnlock(dv);
} catch
if (unlock)
DrvUnlock(dv);
return c;
}
I64 Cluster2Blk(CDrv *dv,I64 c)
{//Drv cluster num to blk num.
DrvChk(dv);
switch (dv->type) {
case DVT_REDSEA:
return c;
case DVT_ISO9660:
case DVT_FAT32:
return dv->data_area+c*dv->spc;
default:
throw('Drv');
}
}
I64 RClustersBlks(CDrv *dv,U8 *buf,I64 c,I64 blks)
{//Accepts blk count, so padding on last cluster is not read.
I64 i;
Bool unlock;
DrvChk(dv);
if (blks<=0) return c;
try {
unlock=DrvLock(dv);
switch (dv->type) {
case DVT_ISO9660:
RBlks(dv,buf,dv->data_area+c*dv->spc,blks);
c+=(blks+dv->spc-1)/dv->spc;
break;
case DVT_REDSEA:
RBlks(dv,buf,c,blks);
c+=blks;
break;
case DVT_FAT32:
while (blks && 0<c<0x0FFFFFF8) {
i=blks;
if (i>dv->spc)
i=dv->spc;
RBlks(dv,buf,dv->data_area+c*dv->spc,i);
buf+=i<<BLK_SIZE_BITS;
c=ClusterNumNext(dv,c,1);
blks-=i;
}
if (blks)
throw('Drv');
break;
default:
throw('Drv');
}
if (unlock)
DrvUnlock(dv);
} catch
if (unlock)
DrvUnlock(dv);
return c;
}
I64 RClusters(CDrv *dv,U8 *buf,I64 c,I64 cnt)
{//Read cluster cnt from drv to buf.
return RClustersBlks(dv,buf,c,cnt*dv->spc);
}
Bool CFileNameTo(U8 *dst,U8 *src)
{
MemSet(dst,0,CDIR_FILENAME_LEN);
if (!FileNameChk(src))
return FALSE;
StrCpy(dst,src);
return TRUE;
}
I64 Name2DirCluster(CDrv *dv,U8 *dirname)
{
Bool cont=TRUE,unlock;
I64 cur_dir_cluster;
CDirEntry de;
U8 *buf=StrNew(dirname),*buf2=StrNew(dirname);
DrvChk(dv);
try {
unlock=DrvLock(dv);
cur_dir_cluster=dv->root_cluster;
while (*buf && cont) {
StrFirstRem(buf,"/",buf2);
if (*buf2) {
switch (dv->type) {
case DVT_REDSEA:
cont=RedSeaFileFind(dv,cur_dir_cluster,buf2,&de,FUF_JUST_DIRS);
break;
case DVT_FAT32:
cont=FAT32FileFind(dv,cur_dir_cluster,buf2,&de,FUF_JUST_DIRS);
break;
case DVT_ISO9660:
cont=ISO1FileFind(dv,cur_dir_cluster,buf2,&de,FUF_JUST_DIRS);
break;
default:
throw('Drv');
}
cur_dir_cluster=de.cluster;
}
}
if (!cont) {
"%s ",dirname;
PrintErr("File not found.\n");
cur_dir_cluster=0;
}
if (unlock)
DrvUnlock(dv);
} catch
if (unlock)
DrvUnlock(dv);
Free(buf);
Free(buf2);
return cur_dir_cluster;
}
I64 Name2ParentDirCluster(CDrv *dv,U8 *dirname)
{
Bool cont=TRUE,unlock;
I64 cur_dir_cluster,cur_dir_cluster2;
CDirEntry de;
U8 *buf=StrNew(dirname),*buf2=StrNew(dirname);
DrvChk(dv);
try {
unlock=DrvLock(dv);
cur_dir_cluster=cur_dir_cluster2=dv->root_cluster;
while (*buf && cont) {
cur_dir_cluster2=cur_dir_cluster;
StrFirstRem(buf,"/",buf2);
if (*buf2) {
switch (dv->type) {
case DVT_REDSEA:
cont=RedSeaFileFind(dv,cur_dir_cluster,buf2,&de,FUF_JUST_DIRS);
break;
case DVT_FAT32:
cont=FAT32FileFind(dv,cur_dir_cluster,buf2,&de,FUF_JUST_DIRS);
break;
case DVT_ISO9660:
cont=ISO1FileFind(dv,cur_dir_cluster,buf2,&de,FUF_JUST_DIRS);
break;
default:
throw('Drv');
}
cur_dir_cluster=de.cluster;
}
}
if (!cont) {
"%s ",dirname;
PrintErr("File not found.\n");
cur_dir_cluster2=0;
}
if (unlock)
DrvUnlock(dv);
} catch
if (unlock)
DrvUnlock(dv);
Free(buf);
Free(buf2);
return cur_dir_cluster2;
}
I64 WClustersBlks(CDrv *dv,U8 *buf,I64 c,I64 blks)
{//Accepts blk count, so padding on last cluster is not written.
I64 i;
Bool unlock;
DrvChk(dv);
if (blks<=0) return c;
try {
unlock=DrvLock(dv);
switch (dv->type) {
case DVT_REDSEA:
WBlks(dv,buf,c,blks);
c=0;
break;
case DVT_FAT32:
while (blks) {
if (!(0<c<0x0FFFFFF8))
throw('Drv');
i=blks;
if (i>dv->spc)
i=dv->spc;
WBlks(dv,buf,dv->data_area+c*dv->spc,i);
buf+=i<<BLK_SIZE_BITS;
c=ClusterNumNext(dv,c);
blks-=i;
}
break;
default:
throw('Drv');
}
if (unlock)
DrvUnlock(dv);
} catch
if (unlock)
DrvUnlock(dv);
return c;
}
I64 WClusters(CDrv *dv,U8 *buf,I64 c,I64 cnt)
{//Write cluster cnt from buf to drv.
return WClustersBlks(dv,buf,c,cnt*dv->spc);
}
I64 ClustersAlloc(CDrv *dv,I64 c=0,I64 cnt=1,Bool contiguous=FALSE)
{//Alloc cluster cnt into chain.
//c=0 means first cluster in chain
DrvChk(dv);
if (cnt<=0) return c;
switch (dv->type) {
case DVT_REDSEA:
return RedSeaAllocClusters(dv,cnt);
case DVT_FAT32:
if (contiguous) {
if (c) throw('File');
return FAT32AllocContiguousClusters(dv,cnt);
} else
return FAT32AllocClusters(dv,c,cnt);
default:
throw('Drv');
}
}
+287 -568
View File
File diff suppressed because it is too large. Load diff
+279
View File
@@ -0,0 +1,279 @@
Bool BootCdProbe(CBlkDev *bd)
{
CKernel *img=CAlloc(CD_BLK_SIZE);
I64 i;
Bool result=FALSE;
"Port: %04X,%04X Unit: %02X ",bd->base0,bd->base1,bd->unit;
if (ATAProbe(bd->base0,bd->base1,bd->unit)==BDT_ATAPI) {
" ATAPI";
if (ATAPIStartStop(bd,tS+5.0,TRUE)) {
" Started";
for (i=0;i<2;i++) {//Retry
if (ATAPIReadBlks2(bd,tS+7.0,img,sys_boot_src.u16[1],1,FALSE)) {
if (img->compile_time==sys_compile_time) {
" Found";
return TRUE;
} else
" Read";
} else
" NoRead";
}
}
}
" Nope\n";
Free(img);
return result;
}
Bool BootCdProbeAll(CBlkDev *bd)
{
I64 d1,d2,i,j,k;
bd->base1=0;
for (k=0;k<256;k++) {
i=-1;
while (TRUE) {
j=PCIClassFind(0x010100+k,++i);
if (j<0)
break;
"Subcode:0x%X Bus:0x%X Dev:0x%X Fun:0x%X\n",k,j.u8[2],j.u8[1],j.u8[0];
d1=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x10);
d2=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x14);
if (d1&1 && d2&1) {
if (bd->base0=d1&~7) {
bd->unit=0;
if (BootCdProbe(bd))
return TRUE;
bd->unit=1;
if (BootCdProbe(bd))
return TRUE;
}
}
d1=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x18);
d2=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x1C);
if (d1&1 && d2&1) {
if (bd->base0=d1&~7) {
bd->unit=0;
if (BootCdProbe(bd))
return TRUE;
bd->unit=1;
if (BootCdProbe(bd))
return TRUE;
}
}
}
}
d1=0x1F0;
d2=0x3F6;
if (bd->base0=d1&~7) {
bd->unit=0;
if (BootCdProbe(bd))
return TRUE;
bd->unit=1;
if (BootCdProbe(bd))
return TRUE;
}
d1=0x170;
d2=0x376;
if (bd->base0=d1&~7) {
bd->unit=0;
if (BootCdProbe(bd))
return TRUE;
bd->unit=1;
if (BootCdProbe(bd))
return TRUE;
}
}
U0 ATARepEntry(I64 base0,I64 base1,I64 unit,I64 irq,U8 *msg,CATARep **_root,I64 *num_hints)
{
I64 type;
base0&=-8;
base1&=-4;
CATARep *tempha;
if (type=ATAProbe(base0,base1,unit)) {
*num_hints+=1;
"\n\n$$PURPLE$$ $$BT+X,\"%d\",LM=\"%d\\n\"$$$$FG$$$$LM,4$$",*num_hints,*num_hints;
if (type==BDT_ATA)
"$$RED$$ATA ";
else
"$$RED$$ATAPI ";
"$$LTBLUE$$%s$$FG$$\nBase0:0x%04X Base1:0x%04X\nIrq:0x%02X Unit:%d$$LM,0$$\n",msg,base0,base1,irq,unit;
if (_root) {
tempha=CAlloc(sizeof(CATARep));
tempha->next=*_root;
*_root=tempha;
tempha->num=*num_hints;
tempha->type=type;
tempha->base0=base0;
tempha->base1=base1;
tempha->unit=unit;
}
}
}
Bool ATARepExitAllApplications()
{
"\nWe're going to probe hardware.\n"
"$$RED$$Exit all other applications.$$FG$$\n"
"Press '$$PURPLE$$p$$FG$$' to probe or '$$PURPLE$$s$$FG$$' to skip.\n";
if (ToUpper(GetChar(,FALSE))=='S')
return TRUE;
else
return FALSE;
}
public I64 ATARep(Bool pmt=TRUE,Bool just_ide=FALSE,CATARep **_root=NULL)
{//Report possible ATA devices by probing. Hard disks and CD/DVDs.
I64 d1,d2,d3,i,j,k,cnt=0,unlock_flags=0,num_hints=0;
#assert NUM_BLKDEVS<=64
Bool old_preempt;
if (_root) *_root=NULL;
if (pmt && ATARepExitAllApplications)
return 0;
old_preempt=Preempt(OFF);
for (i=0;i<NUM_BLKDEVS;i++)
if (dsk.blkdevs[i].bd_signature==BD_SIGNATURE_VAL)
BEqu(&unlock_flags,i,
BlkDevLock(&dsk.blkdevs[i]));
if (!just_ide)
for (k=0;k<256;k++) {
i=-1;
while (TRUE) {
j=PCIClassFind(0x010100+k,++i);
if (j<0)
break;
"\nSubcode:0x%X Bus:0x%X Dev:0x%X Fun:0x%X\n",k,j.u8[2],j.u8[1],j.u8[0];
cnt++;
d1=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x10);
d2=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x14);
d3=PCIReadU8(j.u8[2],j.u8[1],j.u8[0],0x3C);
if (d1&1 && d2&1) {
ATARepEntry(d1,d2,0,d3,"Primary IDE",_root,&num_hints);
ATARepEntry(d1,d2,1,d3,"Primary IDE",_root,&num_hints);
} else {
d1=0x1F0; d2=0x3F6; d3=14;
ATARepEntry(d1,d2,0,d3,"Primary IDE",_root,&num_hints);
ATARepEntry(d1,d2,1,d3,"Primary IDE",_root,&num_hints);
}
d1=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x18);
d2=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x1C);
if (d1&1 && d2&1) {
ATARepEntry(d1,d2,0,d3,"Secondary IDE",_root,&num_hints);
ATARepEntry(d1,d2,1,d3,"Secondary IDE",_root,&num_hints);
} else {
d1=0x170; d2=0x376; d3=15;
ATARepEntry(d1,d2,0,d3,"Secondary IDE",_root,&num_hints);
ATARepEntry(d1,d2,1,d3,"Secondary IDE",_root,&num_hints);
}
}
}
if (!cnt) {
d1=0x1F0; d2=0x3F6; d3=14;
ATARepEntry(d1,d2,0,d3,"Primary IDE",_root,&num_hints);
ATARepEntry(d1,d2,1,d3,"Primary IDE",_root,&num_hints);
d1=0x170; d2=0x376; d3=15;
ATARepEntry(d1,d2,0,d3,"Secondary IDE",_root,&num_hints);
ATARepEntry(d1,d2,1,d3,"Secondary IDE",_root,&num_hints);
}
'\n\n';
for (i=0;i<NUM_BLKDEVS;i++)
if (Bt(&unlock_flags,i))
BlkDevUnlock(&dsk.blkdevs[i]);
Preempt(old_preempt);
return num_hints;
}
CATARep *ATAIDDrvs(CATARep *root,I64 _sys_boot_drv,CATARep **_ata_drv,CATARep **_atapi_drv)
{//This is for when trying to sort-out main hard drives and CD-ROM drives.
CATARep *result=NULL,*tempha=root,*ata_drv=NULL,*atapi_drv=NULL;
CBlkDev *bd;
Bool was_silent=Silent;
try
bd=Let2BlkDev(_sys_boot_drv);
catch {
Fs->catch_except=TRUE;
bd=NULL;
}
Silent(was_silent);
while (tempha) {
if (!result && bd && bd->type==tempha->type) {
if (bd->type==BDT_ATAPI &&
bd->base0==tempha->base0 && bd->unit==tempha->unit)
result=atapi_drv=tempha;
else if (bd->type==BDT_ATA && bd->base0==tempha->base0 &&
bd->base1==tempha->base1 && bd->unit==tempha->unit)
result=ata_drv=tempha;
}
if (!result || result->type!=tempha->type) {
if (tempha->type==BDT_ATA) {
if (!ata_drv || tempha->unit<ata_drv->unit ||
tempha->unit==ata_drv->unit && tempha->num<ata_drv->num)
ata_drv=tempha;
} else if (tempha->type==BDT_ATAPI) {
if (!atapi_drv || tempha->unit<atapi_drv->unit ||
tempha->unit==atapi_drv->unit && tempha->num<atapi_drv->num)
atapi_drv=tempha;
}
}
tempha=tempha->next;
}
if (_ata_drv) *_ata_drv =ata_drv;
if (_atapi_drv) *_atapi_drv=atapi_drv;
return result;
}
CBlkDev *ATAMount(U8 first_drv_let,I64 type,I64 base0,I64 base1,I64 unit)
{
CBlkDev *result;
if (0<=first_drv_let-'A'<NUM_DRVS && (type==BDT_ATA || type==BDT_ATAPI) &&
0<=unit<=1) {
result=BlkDevNextFree(first_drv_let,type);
result->unit=unit;
result->base0=base0;
result->base1=base1;
if (BlkDevAdd(result,FALSE,FALSE))
return result;
}
return NULL;
}
I64 AutoMountIDE()
{//Try to mount hard drive and CD/DVD, automatically. (Kernel.Cfg option).
//It uses 'C' and 'T' as first drive letters or whatever you set
//in config when compiling Kernel.BIN.
I64 result=0;
CATARep *root=NULL,*ata_drv=NULL,*atapi_drv=NULL,*tempha;
ATARep(FALSE,TRUE,&root);
ATAIDDrvs(root,dsk.boot_drv_let,&ata_drv,&atapi_drv);
if (ata_drv && ATAMount(dsk.first_hd_drv_let,BDT_ATA,
ata_drv->base0,ata_drv->base1,ata_drv->unit))
result++;
if (atapi_drv && ATAMount(dsk.first_cd_drv_let,BDT_ATAPI,
atapi_drv->base0,atapi_drv->base1,atapi_drv->unit))
result++;
tempha=root;
while (tempha) {
if (tempha!=ata_drv && tempha!=atapi_drv) {
if (tempha->type==BDT_ATA && ATAMount(dsk.first_hd_drv_let,BDT_ATA,
tempha->base0,tempha->base1,tempha->unit))
result++;
else if (tempha->type==BDT_ATAPI && ATAMount(dsk.first_cd_drv_let,BDT_ATAPI,
tempha->base0,tempha->base1,tempha->unit))
result++;
}
tempha=tempha->next;
}
LinkedLstDel(root);
dsk.auto_mount_ide_cnt=result;
return result;
}
+88 -87
View File
@@ -1,18 +1,18 @@
U0 SetBlkDevLockFwding(CBlkDev *bdev)
{
CBlkDev *bdev1;
U0 BlkDevLockFwdingSet(CBlkDev *bd)
{ //If two blkdevs on same controller, use just one lock
CBlkDev *bd1;
I64 i;
switch (bdev->type) {
switch (bd->type) {
case BDT_RAM:
break;
case BDT_ATA:
case BDT_ATAPI:
for (i=0;i<NUM_BLKDEVS;i++) {
bdev1=&dsk.blkdevs[i];
if (bdev1->bd_signature==BD_SIGNATURE_VAL && bdev!=bdev1 &&
(bdev1->type==BDT_ATAPI || bdev1->type==BDT_ATA) &&
bdev1->base0==bdev->base0) {
bdev->lock_fwding=bdev1;
bd1=&dsk.blkdevs[i];
if (bd1->bd_signature==BD_SIGNATURE_VAL && bd!=bd1 &&
(bd1->type==BDT_ATAPI || bd1->type==BDT_ATA) &&
bd1->base0==bd->base0) {
bd->lock_fwding=bd1;
break;
}
}
@@ -20,74 +20,74 @@ U0 SetBlkDevLockFwding(CBlkDev *bdev)
}
}
I64 BlkDevAdd(CBlkDev *bdev,Bool one_prt,Bool make_free)
I64 BlkDevAdd(CBlkDev *bd,Bool one_drv,Bool make_free)
{
I64 i,j,ext_base,offset,result=0;
CPrt *p;
CBootStruct br;
CDrv *dv;
CRedSeaBoot br;
CMasterBoot mbr;
bdev->bd_signature=BD_SIGNATURE_VAL;
bd->bd_signature=BD_SIGNATURE_VAL;
if (make_free)
p=PrtMakeFree(bdev->first_drv_let+result);
dv=DrvMakeFree(bd->first_drv_let+result);
else
p=PrtNextFree(bdev->first_drv_let+result);
p->bdev=bdev;
p->size=bdev->max_blk+1;
switch (bdev->type) {
dv=DrvNextFree(bd->first_drv_let+result);
dv->bd=bd;
dv->size=bd->max_blk+1;
switch (bd->type) {
case BDT_RAM:
p->pt_signature=PRT_SIGNATURE_VAL;
p->type=PT_REDSEA;
dv->dv_signature=DRV_SIGNATURE_VAL;
dv->type=DVT_REDSEA;
//This is to force creation of a RAM
//drive during boot, so it is probably
//MAlloced to the same addr and can
//be assumed to be already formatted.
//If this line is removed, RAM Drives
//will be allocated on a just-in-time
//will be alloced on a just-in-time
//basis.
if (BlkDevInit(bdev))
if (BlkDevInit(bd))
result++;
else
p->pt_signature=0;
dv->dv_signature=0;
break;
case BDT_ATA:
p->pt_signature=PRT_SIGNATURE_VAL; //Temporarily validate
if (!BlkDevInit(bdev))
p->pt_signature=0; //Revoke validation
dv->dv_signature=DRV_SIGNATURE_VAL; //Temporarily validate
if (!BlkDevInit(bd))
dv->dv_signature=0; //Revoke validation
else {
p->pt_signature=0; //Revoke validation
if (one_prt) {
p->pt_signature=PRT_SIGNATURE_VAL;
dv->dv_signature=0; //Revoke validation
if (one_drv) {
dv->dv_signature=DRV_SIGNATURE_VAL;
result++;
p->type=PT_REDSEA;
p->size=bdev->max_blk+1;
dv->type=DVT_REDSEA;
dv->size=bd->max_blk+1;
//The following read is a test read.
//if it hangs, the drive is not supported.
ATAReadBlks(bdev,&mbr,0,1);
ATAReadBlks(bd,&mbr,0,1);
break;
}
offset=0;
ext_base=INVALID_CLUSTER;
while (TRUE) {
ATAReadBlks(bdev,&mbr,offset,1);
ATAReadBlks(bd,&mbr,offset,1);
if (mbr.signature!=0xAA55)
break;
j=-1;
for (i=0;i<4;i++) {
if (mbr.p[i].type) {
if (make_free)
p=PrtMakeFree(bdev->first_drv_let+result);
dv=DrvMakeFree(bd->first_drv_let+result);
else
p=PrtNextFree(bdev->first_drv_let+result);
p->bdev=bdev;
p->offset=mbr.p[i].offset+offset;
p->size =mbr.p[i].size;
dv=DrvNextFree(bd->first_drv_let+result);
dv->bd=bd;
dv->base_offset=mbr.p[i].offset+offset;
dv->size =mbr.p[i].size;
switch (mbr.p[i].type) {
case MBR_PT_REDSEA:
p->pt_signature=PRT_SIGNATURE_VAL;
dv->dv_signature=DRV_SIGNATURE_VAL;
result++;
p->type=PT_REDSEA;
RedSeaFSPrtInit(p);
dv->type=DVT_REDSEA;
RedSeaDrvInit(dv);
break;
case MBR_PT_FAT32a:
case MBR_PT_FAT32b:
@@ -95,30 +95,30 @@ I64 BlkDevAdd(CBlkDev *bdev,Bool one_prt,Bool make_free)
case MBR_PT_FAT32d:
case MBR_PT_FAT32e:
case MBR_PT_FAT32f:
ATAReadBlks(bdev,&br,p->offset,1);
p->pt_signature=PRT_SIGNATURE_VAL;
ATAReadBlks(bd,&br,dv->base_offset,1);
dv->dv_signature=DRV_SIGNATURE_VAL;
result++;
if (br.signature==MBR_PT_REDSEA) {
p->type=PT_REDSEA;
RedSeaFSPrtInit(p);
dv->type=DVT_REDSEA;
RedSeaDrvInit(dv);
} else {
p->type=PT_FAT32;
FAT32PrtInit(p);
dv->type=DVT_FAT32;
FAT32DrvInit(dv);
}
break;
case MBR_PT_NTFS:
p->pt_signature=PRT_SIGNATURE_VAL;
dv->dv_signature=DRV_SIGNATURE_VAL;
result++;
p->type=PT_NTFS;
dv->type=DVT_NTFS;
break;
case 5:
case 15:
j=i;
break;
default:
p->pt_signature=PRT_SIGNATURE_VAL;
dv->dv_signature=DRV_SIGNATURE_VAL;
result++;
p->type=PT_UNKNOWN;
dv->type=DVT_UNKNOWN;
}
}
}
@@ -135,26 +135,26 @@ I64 BlkDevAdd(CBlkDev *bdev,Bool one_prt,Bool make_free)
}
break;
case BDT_ATAPI:
p->pt_signature=PRT_SIGNATURE_VAL;
dv->dv_signature=DRV_SIGNATURE_VAL;
result++;
p->type=PT_ISO9660; //Start with this
p->size =0;
dv->type=DVT_ISO9660; //Start with this
dv->size =0;
break;
}
if (result)
SetBlkDevLockFwding(bdev);
BlkDevLockFwdingSet(bd);
else
MemSet(bdev,0,sizeof(CBlkDev));
MemSet(bd,0,sizeof(CBlkDev));
return result;
}
Bool DrvEnable(U8 drv_let,Bool val)
{//Can unmount or remount, but not mount the first time.
CPrt *p;
CDrv *dv;
Bool result=FALSE;
try {
p=Drv2Prt(drv_let);
result=!LBEqu(&p->type,PTf_DISABLE,!val);
dv=Let2Drv(drv_let);
result=!LBEqu(&dv->type,DVTf_DISABLE,!val);
} catch
Fs->catch_except=TRUE;
return result;
@@ -172,14 +172,14 @@ CATARep *ATARepFind(CATARep *haystack_root,I64 needle_num)
U0 Mount(Bool repartition=FALSE)
{//Mount a drive.
CBlkDev *bdev;
I64 first_prt_num,type,unit,num_hints;
CBlkDev *bd;
I64 first_drv_num,type,unit,num_hints;
U8 blks_buf[128],addr_buf[128],base0_buf[128],base1_buf[128];
Bool add;
CATARep *root,*tempha;
do {
PrtRep;
DrvRep;
"\n****** Mount Drives ******\n"
"The first drive letter is the letter\n"
"of the first partition. If adding\n"
@@ -187,9 +187,9 @@ U0 Mount(Bool repartition=FALSE)
"If more than one partition is present\n"
"they will be lettered in sequence.\n"
"\nFirst Drive Letter ($$PURPLE$$<ENTER>$$FG$$ to exit):";
first_prt_num=ToUpper(GetChar)-'A';
first_drv_num=ToUpper(GetChar)-'A';
'\n';
if (0<=first_prt_num<NUM_PRTS) {
if (0<=first_drv_num<NUM_DRVS) {
"\t$$PURPLE$$1$$FG$$=RAM\n\t$$PURPLE$$2$$FG$$=ATA(Harddisk)\n"
"\t$$PURPLE$$3$$FG$$=ATAPI(CD-ROM)\nType:";
type=GetChar-'0';
@@ -235,35 +235,35 @@ U0 Mount(Bool repartition=FALSE)
}
if (BDT_NULL<type<BDT_NUM_TYPES && 0<=unit<=1) {
bdev=BlkDevNextFree(first_prt_num+'A',type);
bdev->unit=unit;
bd=BlkDevNextFree(first_drv_num+'A',type);
bd->unit=unit;
if (type==BDT_RAM) {
if (!*addr_buf) StrCpy(addr_buf,"0");
bdev->RAM_dsk=Str2I64(addr_buf);
bdev->max_blk=Str2I64(blks_buf)-1;
bd->RAM_dsk=Str2I64(addr_buf);
bd->max_blk=Str2I64(blks_buf)-1;
}
if (type==BDT_ATA ||
type==BDT_ATAPI) {
bdev->base0=Str2I64(base0_buf);
bdev->base1=Str2I64(base1_buf);
bd->base0=Str2I64(base0_buf);
bd->base1=Str2I64(base1_buf);
}
add=TRUE;
if (type==BDT_ATA && repartition) {
"\nReformat WHOLE drive!";
if (YorN) {
if (!BlkDevAdd(bdev,TRUE,TRUE))
if (!BlkDevAdd(bd,TRUE,TRUE))
"\n\n$$BK,1$$$$RED$$Operation Failed$$BK,0$$$$FG$$\n\n";
else
CallExtStr("PrtDsk",bdev->first_drv_let);
CallExtStr("PrtDsk",bd->first_drv_let);
add=FALSE;
}
}
if (add && !BlkDevAdd(bdev,FALSE,TRUE))
if (add && !BlkDevAdd(bd,FALSE,TRUE))
"\n\n$$BK,1$$$$RED$$Operation Failed$$BK,0$$$$FG$$\n\n";
} else
"\n\n$$BK,1$$$$RED$$Operation Failed$$BK,0$$$$FG$$\n\n";
}
} while (0<=first_prt_num<NUM_PRTS);
} while (0<=first_drv_num<NUM_DRVS);
}
I64 SysGetI64()
@@ -273,7 +273,7 @@ I64 SysGetI64()
return Str2I64(st,16);
}
Bool GetBaseUnit(CBlkDev *bdev)
Bool GetBaseUnit(CBlkDev *bd)
{
I64 ch;
Bool probe;
@@ -284,25 +284,26 @@ Bool GetBaseUnit(CBlkDev *bdev)
else
StreamPrint("probe=TRUE;");
};
if (!probe || !BootCdProbeAll(bdev)) {
if (!probe || !BootCdProbeAll(bd)) {
"\nDon't worry. This is not a product\n"
"registration. TempleOS just needs the\n"
"I/O port numbers for the CD-ROM.\n"
"\nRetry the ports above or check Windows\n"
"system information under I/O ports for\n"
"'IDE', 'ATA' or 'SATA'.\n"
"In Linux, use 'lspci -v' for ports.\n"
"\n\nEnter 4-digit hex I/O Port number.\n"
"CD-ROM I/O Port Base0: 0x";
bdev->base0=SysGetI64;
bdev->base1=0;
bdev->unit =0;
if (bdev->base0) {
bd->base0=SysGetI64;
bd->base1=0;
bd->unit =0;
if (bd->base0) {
"\nUnit (0 or 1): ";
do ch=GetChar(,FALSE);
while (!('0'<=ch<='1'));
'' ch;
bdev->unit=ch-'0';
dsk.cdrom_boot_is_good=BootCdProbe(bdev);
bd->unit=ch-'0';
dsk.cdrom_boot_is_good=BootCdProbe(bd);
return TRUE;
} else {
dsk.cdrom_boot_is_good=FALSE;
@@ -314,12 +315,12 @@ Bool GetBaseUnit(CBlkDev *bdev)
U0 BlkDevsInitAll()
{
CBlkDev *bdev;
CBlkDev *bd;
I64 i;
dsk.blkdevs=CAlloc(sizeof(CBlkDev)*NUM_BLKDEVS);
dsk.prts=CAlloc(sizeof(CPrt)*NUM_PRTS);
for (i=0;i<NUM_PRTS;i++)
dsk.drv_to_prt[i]=&dsk.prts[i];
dsk.drvs=CAlloc(sizeof(CDrv)*NUM_DRVS);
for (i=0;i<NUM_DRVS;i++)
dsk.let_to_drv[i]=&dsk.drvs[i];
text.raw_col=0;
#exe {
if (kernel_cfg->opts[CFG_AUTO_MOUNT_IDE])
@@ -328,5 +329,5 @@ U0 BlkDevsInitAll()
StreamDoc(kernel_cfg->add_dev);
StreamPrint("#exe {OptOn(OPTf_WARN_PAREN);}");
};
PrtRep;
DrvRep;
}
+136 -128
View File
@@ -1,9 +1,9 @@
Bool MapDrv(U8 drv_let,CPrt *p)
Bool MapDrv(U8 drv_let,CDrv *dv)
{//Make drive letter map to another.
drv_let=ToUpper(drv_let);
if ('A'<=drv_let<='Z') {
dsk.drv_to_prt[drv_let-'A']=p;
p->drv_let=drv_let;
dsk.let_to_drv[drv_let-'A']=dv;
dv->drv_let=drv_let;
return TRUE;
} else
return FALSE;
@@ -11,22 +11,22 @@ Bool MapDrv(U8 drv_let,CPrt *p)
Bool Drv(U8 drv_let)
{//Set drive. You can set drive with $LK,"Cd",A="MN:Cd"$() as well.
CPrt *p=Drv2Prt(drv_let);
CBlkDev *bdev=p->bdev;
BlkDevChk(bdev);
if (p!=Fs->cur_prt) {
if (bdev->flags & BDF_REMOVABLE && !(bdev->flags & BDF_INITIALIZED))
ChgDsk(Prt2Drv(p));
if (bdev->type==BDT_RAM)
BlkDevInit(bdev);
CDrv *dv=Let2Drv(drv_let);
CBlkDev *bd=dv->bd;
BlkDevChk(bd);
if (dv!=Fs->cur_dv) {
if (bd->flags & BDF_REMOVABLE && !(bd->flags & BDF_INITIALIZED))
ChgDsk(Drv2Let(dv));
if (bd->type==BDT_RAM)
BlkDevInit(bd);
}
Fs->cur_prt=p;
Fs->cur_dv=dv;
Free(Fs->cur_dir);
Fs->cur_dir=StrNew("/");
switch (p->type) {
case PT_REDSEA:
case PT_FAT32:
case PT_ISO9660:
switch (dv->type) {
case DVT_REDSEA:
case DVT_FAT32:
case DVT_ISO9660:
return TRUE;
default:
PrintErr("File System Not Supported\n");
@@ -34,19 +34,21 @@ Bool Drv(U8 drv_let)
}
}
Bool Cd(U8 *dirname,Bool make_dirs=FALSE)
Bool Cd(U8 *dirname=NULL,Bool make_dirs=FALSE)
{//Change directory. Optionally, make directories, too.
I64 maxlen,cur_dir_cluster=0;
U8 *chg_to_buf,*new_cur_dir,*buf;
CPrt *p;
CDrv *dv;
Bool result=TRUE;
if (!*dirname)
if (!dirname)
dirname="::/Home";
else if (!*dirname)
return TRUE;
if (dirname[1]==':') {
if (*dirname==':') {
if (Fs->cur_prt->drv_let!=*sys_acct && !Drv(*dirname))
if (Fs->cur_dv!=Let2Drv(':') && !Drv(*dirname))
return FALSE;
} else if (Fs->cur_prt!=Drv2Prt(*dirname) && !Drv(*dirname))
} else if (Fs->cur_dv!=Let2Drv(*dirname) && !Drv(*dirname))
return FALSE;
dirname+=2;
}
@@ -70,38 +72,31 @@ Bool Cd(U8 *dirname,Bool make_dirs=FALSE)
if (!*new_cur_dir)
StrCpy(new_cur_dir,"/");
} else if (StrCmp(buf,".") && *buf) {
if (!StrCmp(buf,"HOME")) {
result=Cd(sys_acct);
Free(new_cur_dir);
new_cur_dir=MAlloc(maxlen+StrLen(sys_acct));
StrCpy(new_cur_dir,sys_acct+2);
} else {
p=Fs->cur_prt;
cur_dir_cluster=Name2DirCluster(p,new_cur_dir);
switch (p->type) {
case PT_REDSEA:
result=RedSeaFSCd(buf,cur_dir_cluster);
break;
case PT_FAT32:
result=FAT32Cd(buf,cur_dir_cluster);
break;
case PT_ISO9660:
result=ISO1Cd(buf,cur_dir_cluster);
break;
default:
PrintErr("File System Not Supported\n");
result=FALSE;
}
if (!result && make_dirs) {
Free(Fs->cur_dir);
Fs->cur_dir=StrNew(new_cur_dir);
result=MkDir(buf);
}
if (result) {
if (StrCmp(new_cur_dir,"/"))
CatPrint(new_cur_dir,"/");
CatPrint(new_cur_dir,buf);
}
dv=Fs->cur_dv;
cur_dir_cluster=Name2DirCluster(dv,new_cur_dir);
switch (dv->type) {
case DVT_REDSEA:
result=RedSeaCd(buf,cur_dir_cluster);
break;
case DVT_FAT32:
result=FAT32Cd(buf,cur_dir_cluster);
break;
case DVT_ISO9660:
result=ISO1Cd(buf,cur_dir_cluster);
break;
default:
PrintErr("File System Not Supported\n");
result=FALSE;
}
if (!result && make_dirs) {
Free(Fs->cur_dir);
Fs->cur_dir=StrNew(new_cur_dir);
result=MkDir(buf);
}
if (result) {
if (StrCmp(new_cur_dir,"/"))
CatPrint(new_cur_dir,"/");
CatPrint(new_cur_dir,buf);
}
}
}
@@ -114,17 +109,17 @@ Bool Cd(U8 *dirname,Bool make_dirs=FALSE)
}
U0 FileAccessDel(CFileAccess *fa)
{//Change back to old cur_dir and prt.
CBlkDev *bdev;
{//Change back to old cur_dir and drv.
CBlkDev *bd;
if (!fa) return;
bdev=fa->old_prt->bdev;
if (!(bdev->flags & BDF_INIT_IN_PROGRESS)) {
bd=fa->old_dv->bd;
if (!(bd->flags & BDF_INIT_IN_PROGRESS)) {
if (fa->old_dir) {
Drv(Prt2Drv(fa->old_prt));
Drv(Drv2Let(fa->old_dv));
Cd(fa->old_dir);
}
} else {
Fs->cur_prt=fa->old_prt;
Fs->cur_dv=fa->old_dv;
Free(Fs->cur_dir);
Fs->cur_dir=StrNew("/");
}
@@ -134,23 +129,21 @@ U0 FileAccessDel(CFileAccess *fa)
}
CFileAccess *FileAccessNew(U8 *_mask,Bool make_mask=FALSE,Bool make_dirs=FALSE,Bool no_mask=FALSE)
{//Save cur_dir and prt. Change to new dir.
{//Save cur_dir and drv. Change to new dir.
Bool valid=TRUE,old_silent;
U8 *buf,*mask,*temp_mask;
CFileAccess *fa=CAlloc(sizeof(CFileAccess));
mask=MStrUtil(_mask,SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
temp_mask=mask;
fa->old_dir=StrNew(Fs->cur_dir);
fa->old_prt=Fs->cur_prt;
fa->old_dv=Fs->cur_dv;
if (*mask && mask[1]==':') {
if (Fs->cur_prt!=Drv2Prt(*mask) && !Drv(*mask))
if (Fs->cur_dv!=Let2Drv(*mask) && !Drv(*mask))
valid=FALSE;
mask+=2;
}
if (StrMatch("HOME",mask) && Fs->cur_prt!=Drv2Prt(*sys_acct))
Drv(*sys_acct);
fa->p=Fs->cur_prt;
PrtChk(fa->p);
fa->dv=Fs->cur_dv;
DrvChk(fa->dv);
buf=MAlloc(StrLen(mask)+2);
StrCpy(buf,mask);
fa->mask=MAlloc(StrLen(mask)+2);
@@ -169,7 +162,7 @@ CFileAccess *FileAccessNew(U8 *_mask,Bool make_mask=FALSE,Bool make_dirs=FALSE,B
fa->mask=StrNew("*");
} else {
if (!make_dirs || FileNameChk(fa->mask)) {
old_silent=Silent(ON);
old_silent=Silent;
//Try mask to see if Dir. If Dir, change to dir and set to "*".
if (Cd(fa->mask,make_dirs)) {
Free(fa->mask);
@@ -184,7 +177,6 @@ CFileAccess *FileAccessNew(U8 *_mask,Bool make_mask=FALSE,Bool make_dirs=FALSE,B
if (!valid) {
FileAccessDel(fa);
fa=NULL;
// throw('File');
}
return fa;
}
@@ -219,7 +211,7 @@ $LK,"DirTreeDel",A="MN:DirTreeDel"$() or $LK,"DirTreeDel2",A="MN:DirTreeDel2"$()
Bool IsDir(U8 *dir_name)
{//Is a str a valid, existing Dir?
U8 *mask=MStrPrint("%s/*",dir_name);
Bool result,old_silent=Silent(ON);
Bool result,old_silent=Silent;
CFileAccess *fa;
if (fa=FileAccessNew(mask)) {
FileAccessDel(fa);
@@ -248,14 +240,14 @@ I64 Del(U8 *files_find_mask,Bool print_msg=TRUE)
I64 result=0;
CFileAccess *fa;
if (fa=FileAccessNew(files_find_mask)) {
switch (fa->p->type) {
case PT_REDSEA:
result=RedSeaFSFilesDel(fa->p,Fs->cur_dir,fa->mask,0,FALSE,print_msg);
switch (fa->dv->type) {
case DVT_REDSEA:
result=RedSeaFilesDel(fa->dv,Fs->cur_dir,fa->mask,0,FALSE,print_msg);
break;
case PT_FAT32:
result=FAT32FilesDel(fa->p,Fs->cur_dir,fa->mask,0,FALSE,print_msg);
case DVT_FAT32:
result=FAT32FilesDel(fa->dv,Fs->cur_dir,fa->mask,0,FALSE,print_msg);
break;
case PT_ISO9660:
case DVT_ISO9660:
PrintErr("Not Writable\n");
break;
default:
@@ -266,7 +258,7 @@ I64 Del(U8 *files_find_mask,Bool print_msg=TRUE)
return result;
}
U8 *FileRead(U8 *filename,I64 *_size=NULL,I64 *_attr=NULL,Bool raw=FALSE)
U8 *FileRead(U8 *filename,I64 *_size=NULL,I64 *_attr=NULL)
{//Read whole file from disk.
CHashGeneric *temph;
U8 *absname,*altname,*curname,*result=NULL;
@@ -275,8 +267,8 @@ U8 *FileRead(U8 *filename,I64 *_size=NULL,I64 *_attr=NULL,Bool raw=FALSE)
CArcCompress *ac;
absname=FileNameAbs(filename);
altname=ToggleZorNotZ(absname);
if (!raw && ((temph=HashFind(absname,adam_task->hash_table,HTT_FILE))||
(temph=HashFind(altname,adam_task->hash_table,HTT_FILE)))) {
if ((temph=HashFind(absname,adam_task->hash_table,HTT_FILE))||
(temph=HashFind(altname,adam_task->hash_table,HTT_FILE))) {
size=temph->user_data1;
result=MAlloc(size+1);
MemCpy(result,temph->user_data0,size);
@@ -289,15 +281,15 @@ U8 *FileRead(U8 *filename,I64 *_size=NULL,I64 *_attr=NULL,Bool raw=FALSE)
else
curname=altname;
if (fa=FileAccessNew(curname)) {
switch (fa->p->type) {
case PT_REDSEA:
result=RedSeaFSFileRead(fa->p,Fs->cur_dir,fa->mask,&size,&attr);
switch (fa->dv->type) {
case DVT_REDSEA:
result=RedSeaFileRead(fa->dv,Fs->cur_dir,fa->mask,&size,&attr);
break;
case PT_FAT32:
result=FAT32FileRead(fa->p,Fs->cur_dir,fa->mask,&size,&attr);
case DVT_FAT32:
result=FAT32FileRead(fa->dv,Fs->cur_dir,fa->mask,&size,&attr);
break;
case PT_ISO9660:
result=ISO1FileRead(fa->p,Fs->cur_dir,fa->mask,&size,&attr);
case DVT_ISO9660:
result=ISO1FileRead(fa->dv,Fs->cur_dir,fa->mask,&size,&attr);
break;
default:
PrintErr("File System Not Supported\n");
@@ -315,15 +307,15 @@ U8 *FileRead(U8 *filename,I64 *_size=NULL,I64 *_attr=NULL,Bool raw=FALSE)
if (fa=FileAccessNew(curname)) {
while (!result && StrCmp(Fs->cur_dir,"/")) {
Cd("..");
switch (Fs->cur_prt->type) {
case PT_REDSEA:
result=RedSeaFSFileRead(fa->p,Fs->cur_dir,fa->mask,&size,&attr);
switch (Fs->cur_dv->type) {
case DVT_REDSEA:
result=RedSeaFileRead(fa->dv,Fs->cur_dir,fa->mask,&size,&attr);
break;
case PT_FAT32:
result=FAT32FileRead(fa->p,Fs->cur_dir,fa->mask,&size,&attr);
case DVT_FAT32:
result=FAT32FileRead(fa->dv,Fs->cur_dir,fa->mask,&size,&attr);
break;
case PT_ISO9660:
result=ISO1FileRead(fa->p,Fs->cur_dir,fa->mask,&size,&attr);
case DVT_ISO9660:
result=ISO1FileRead(fa->dv,Fs->cur_dir,fa->mask,&size,&attr);
break;
default:
PrintErr("File System Not Supported\n");
@@ -336,10 +328,10 @@ U8 *FileRead(U8 *filename,I64 *_size=NULL,I64 *_attr=NULL,Bool raw=FALSE)
"%s ",filename;
PrintErr("File not found.\n");
}
if (result && !raw && attr & RS_ATTR_RESIDENT)
if (result && attr & RS_ATTR_RESIDENT)
HashGenericAdd(curname,HTT_FILE,AMAllocIdentical(result),size,0,adam_task);
}
if (result && !raw && attr & RS_ATTR_COMPRESSED) {
if (result && attr & RS_ATTR_COMPRESSED) {
ac=result;
size=ac->expanded_size;
result=ExpandBuf(ac);
@@ -359,7 +351,7 @@ Bool FileFind(U8 *filename,CDirEntry *_de=NULL,I64 fuf_flags=0)
U8 *altname,*curname,*full_name=NULL;
CDirEntry de;
CFileAccess *fa;
Bool result=FALSE;
Bool result=FALSE,old_silent;
if (fuf_flags&~FUG_FILE_FIND)
throw('FUF');
if (!filename) return FALSE;
@@ -373,23 +365,31 @@ Bool FileFind(U8 *filename,CDirEntry *_de=NULL,I64 fuf_flags=0)
curname=filename;
else
curname=altname;
if (fa=FileAccessNew(curname)) {
cur_dir_cluster=Name2DirCluster(fa->p,Fs->cur_dir);
switch (fa->p->type) {
case PT_REDSEA:
result=RedSeaFSFileFind(fa->p,cur_dir_cluster,fa->mask,&de,fuf_flags);
old_silent=Silent;
if (!(fa=FileAccessNew(curname)))
Silent(old_silent);
else {
Silent(old_silent);
cur_dir_cluster=Name2DirCluster(fa->dv,Fs->cur_dir);
switch (fa->dv->type) {
case DVT_REDSEA:
result=RedSeaFileFind(fa->dv,cur_dir_cluster,fa->mask,&de,fuf_flags);
break;
case PT_FAT32:
result=FAT32FileFind(fa->p,cur_dir_cluster,fa->mask,&de,fuf_flags);
case DVT_FAT32:
result=FAT32FileFind(fa->dv,cur_dir_cluster,fa->mask,&de,fuf_flags);
break;
case PT_ISO9660:
result=ISO1FileFind(fa->p,cur_dir_cluster,fa->mask,&de,fuf_flags);
case DVT_ISO9660:
result=ISO1FileFind(fa->dv,cur_dir_cluster,fa->mask,&de,fuf_flags);
break;
default:
PrintErr("File System Not Supported\n");
}
if (result && _de)
full_name=MStrPrint("%C:%s/%s",Fs->cur_prt->drv_let,Fs->cur_dir,de.name);
if (result && _de) {
if (StrCmp(Fs->cur_dir,"/"))
full_name=MStrPrint("%C:%s/%s",Drv2Let(Fs->cur_dv),Fs->cur_dir,de.name);
else
full_name=MStrPrint("%C:/%s",Drv2Let(Fs->cur_dv),de.name);
}
FileAccessDel(fa);
}
}
@@ -398,27 +398,35 @@ Bool FileFind(U8 *filename,CDirEntry *_de=NULL,I64 fuf_flags=0)
curname=filename;
else
curname=altname;
if (fa=FileAccessNew(curname)) {
cur_dir_cluster=Name2DirCluster(fa->p,Fs->cur_dir);
old_silent=Silent;
if (!(fa=FileAccessNew(curname)))
Silent(old_silent);
else {
Silent(old_silent);
cur_dir_cluster=Name2DirCluster(fa->dv,Fs->cur_dir);
while (!result && StrCmp(Fs->cur_dir,"/")) {
Cd("..");
cur_dir_cluster=Name2DirCluster(fa->p,Fs->cur_dir);
switch (fa->p->type) {
case PT_REDSEA:
result=RedSeaFSFileFind(fa->p,cur_dir_cluster,fa->mask,&de,fuf_flags);
cur_dir_cluster=Name2DirCluster(fa->dv,Fs->cur_dir);
switch (fa->dv->type) {
case DVT_REDSEA:
result=RedSeaFileFind(fa->dv,cur_dir_cluster,fa->mask,&de,fuf_flags);
break;
case PT_FAT32:
result=FAT32FileFind(fa->p,cur_dir_cluster,fa->mask,&de,fuf_flags);
case DVT_FAT32:
result=FAT32FileFind(fa->dv,cur_dir_cluster,fa->mask,&de,fuf_flags);
break;
case PT_ISO9660:
result=ISO1FileFind(fa->p,cur_dir_cluster,fa->mask,&de,fuf_flags);
case DVT_ISO9660:
result=ISO1FileFind(fa->dv,cur_dir_cluster,fa->mask,&de,fuf_flags);
break;
default:
PrintErr("File System Not Supported\n");
}
}
if (result && _de)
full_name=MStrPrint("%C:%s/%s",Fs->cur_prt->drv_let,Fs->cur_dir,de.name);
if (result && _de) {
if (StrCmp(Fs->cur_dir,"/"))
full_name=MStrPrint("%C:%s/%s",Drv2Let(Fs->cur_dv),Fs->cur_dir,de.name);
else
full_name=MStrPrint("%C:/%s",Drv2Let(Fs->cur_dv),de.name);
}
FileAccessDel(fa);
}
}
@@ -434,7 +442,7 @@ Bool FileFind(U8 *filename,CDirEntry *_de=NULL,I64 fuf_flags=0)
}
I64 FileWrite(U8 *filename,U8 *fbuf,
I64 size,CDate cdt=0,I64 attr=0,Bool raw=FALSE)
I64 size,CDate cdt=0,I64 attr=0)
{//Write whole file to disk.
I64 c=0;
CHashGeneric *temph;
@@ -442,34 +450,34 @@ I64 FileWrite(U8 *filename,U8 *fbuf,
U8 *fbuf2,*absname=FileNameAbs(filename);
if (fa=FileAccessNew(filename,FALSE,TRUE)) {
attr=FileAttr(fa->mask,attr);
if (attr&RS_ATTR_COMPRESSED && !raw) {
if (attr&RS_ATTR_COMPRESSED) {
fbuf=CompressBuf(fbuf,size);
size=fbuf(CArcCompress *)->compressed_size;
fbuf2=fbuf;
} else
fbuf2=NULL;
if (!cdt) cdt=Now;
switch (fa->p->type) {
case PT_REDSEA:
c=RedSeaFSFileWrite(fa->p,Fs->cur_dir,fa->mask,fbuf,size,cdt,attr);
switch (fa->dv->type) {
case DVT_REDSEA:
c=RedSeaFileWrite(fa->dv,Fs->cur_dir,fa->mask,fbuf,size,cdt,attr);
break;
case PT_FAT32:
c=FAT32FileWrite(fa->p,Fs->cur_dir,fa->mask,fbuf,size,cdt,attr);
case DVT_FAT32:
c=FAT32FileWrite(fa->dv,Fs->cur_dir,fa->mask,fbuf,size,cdt,attr);
break;
case PT_ISO9660:
case DVT_ISO9660:
PrintErr("Not Writable\n");
break;
default:
PrintErr("File System Not Supported\n");
}
if (temph=HashFind(absname,adam_task->hash_table,HTT_FILE)) {
if (!raw && attr & RS_ATTR_RESIDENT) {
if (attr & RS_ATTR_RESIDENT) {
Free(temph->user_data0);
temph->user_data0=AMAllocIdentical(fbuf);
temph->user_data1=size;
} else
HashRemDel(temph,adam_task->hash_table);
} else if (!raw && attr & RS_ATTR_RESIDENT)
} else if (attr & RS_ATTR_RESIDENT)
HashGenericAdd(absname,HTT_FILE,AMAllocIdentical(fbuf),size,0,adam_task);
Free(fbuf2);
FileAccessDel(fa);
+65 -65
View File
@@ -93,14 +93,14 @@ Bool MkDir(U8 *filename)
else {
"Make Directory:%s\n",filename;
name=MStrUtil(fa->mask,SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
switch (fa->p->type) {
case PT_REDSEA:
result=RedSeaFSMkDir(fa->p,Fs->cur_dir,name);
switch (fa->dv->type) {
case DVT_REDSEA:
result=RedSeaMkDir(fa->dv,Fs->cur_dir,name);
break;
case PT_FAT32:
result=FAT32MkDir(fa->p,Fs->cur_dir,name);
case DVT_FAT32:
result=FAT32MkDir(fa->dv,Fs->cur_dir,name);
break;
case PT_ISO9660:
case DVT_ISO9660:
PrintErr("Not Writable\n");
break;
default:
@@ -119,14 +119,14 @@ I64 SysDel(U8 *wild,Bool make_mask) //this is dangerous
I64 result=0;
CFileAccess *fa;
if (fa=FileAccessNew(wild,make_mask)) {
switch (fa->p->type) {
case PT_REDSEA:
result=RedSeaFSFilesDel(fa->p,Fs->cur_dir,fa->mask,0,TRUE,TRUE);
switch (fa->dv->type) {
case DVT_REDSEA:
result=RedSeaFilesDel(fa->dv,Fs->cur_dir,fa->mask,0,TRUE,TRUE);
break;
case PT_FAT32:
result=FAT32FilesDel(fa->p,Fs->cur_dir,fa->mask,0,TRUE,TRUE);
case DVT_FAT32:
result=FAT32FilesDel(fa->dv,Fs->cur_dir,fa->mask,0,TRUE,TRUE);
break;
case PT_ISO9660:
case DVT_ISO9660:
PrintErr("Not Writable\n");
break;
default:
@@ -137,39 +137,39 @@ I64 SysDel(U8 *wild,Bool make_mask) //this is dangerous
return result;
}
U0 Fmt(I64 drv_let,Bool quick=TRUE,Bool confirm=TRUE,I64 type=PT_FAT32)
U0 Fmt(I64 drv_let,Bool quick=TRUE,Bool confirm=TRUE,I64 type=DVT_FAT32)
{//Format hard drive or RAM drive.
//$BK,1$Warning:$BK,0$ Destroys all previous info.
//quick=FALSE means fill entire drive
//with zeros.
//Choose $LK,"PT_FAT32",A="MN:PT_FAT32"$ or $LK,"PT_REDSEA",A="MN:PT_REDSEA"$.
//Choose $LK,"DVT_FAT32",A="MN:DVT_FAT32"$ or $LK,"DVT_REDSEA",A="MN:DVT_REDSEA"$.
//You don't format a CD-ROM with this.
CPrt *p=Drv2Prt(drv_let);
CDrv *dv=Let2Drv(drv_let);
Bool old_silent=IsSilent;
if (confirm && !AreYouSure)
return;
if (!p) {
if (!dv) {
PrintErr("Invalid Drive\n");
return;
}
switch (type) {
case PT_REDSEA:
Silent(ON);
case DVT_REDSEA:
Silent;
Drv(drv_let);
Silent(old_silent);
RedSeaFSFmt(drv_let,quick);
DskCacheInvalidate(Drv2Prt(drv_let));
RedSeaFmt(drv_let,quick);
DskCacheInvalidate(Let2Drv(drv_let));
Drv(drv_let);
break;
case PT_FAT32:
Silent(ON);
case DVT_FAT32:
Silent;
Drv(drv_let);
Silent(old_silent);
FAT32Fmt(drv_let,quick);
DskCacheInvalidate(Drv2Prt(drv_let));
DskCacheInvalidate(Let2Drv(drv_let));
Drv(drv_let);
break;
case PT_ISO9660:
case DVT_ISO9660:
PrintErr("Not Writable\n");
break;
default:
@@ -179,34 +179,34 @@ U0 Fmt(I64 drv_let,Bool quick=TRUE,Bool confirm=TRUE,I64 type=PT_FAT32)
U0 CDImageRead(U8 cd_drv_let,U8 *out_name)
{//Read entire CD/DVD image into ISO file.
CBlkDev *bdev=Drv2BlkDev(cd_drv_let);
CPrt *p=Drv2Prt(cd_drv_let);
CBlkDev *bd=Let2BlkDev(cd_drv_let);
CDrv *dv=Let2Drv(cd_drv_let);
U8 *buf=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS),
*out_name2=DftExt(out_name,"ISO");
CFile *f=FOpen(out_name2,"w");
I64 n,spc=bdev->blk_size>>BLK_SIZE_BITS,blk=0,cnt,retry;
BlkDevInit(bdev);
if (bdev->type!=BDT_ATAPI)
I64 n,spc=bd->blk_size>>BLK_SIZE_BITS,blk=0,cnt,retry;
BlkDevInit(bd);
if (bd->type!=BDT_ATAPI)
throw('BlkDev');
if (!out_name)
out_name=dsk.dft_iso_filename;
cnt=CeilU64(p->size,spc);
cnt=CeilU64(dv->size,spc);
while (cnt>0) {
if (cnt>COPY_BUF_BLKS)
n=COPY_BUF_BLKS;
else
n=cnt;
if (n>bdev->max_reads)
n=bdev->max_reads;
if (n>bd->max_reads)
n=bd->max_reads;
retry=4;
while (--retry)
if (ATAPIReadBlks2(bdev,tS+7.0+0.004*n/spc,buf,blk/spc,n/spc,TRUE))
if (ATAPIReadBlks2(bd,tS+7.0+0.004*n/spc,buf,blk/spc,n/spc,TRUE))
//n is 0x800 if max_reads. Up to 8 additional seconds
break;
if (!retry)
ATAPIReadBlks2(bdev,0,buf,blk/spc,n/spc,TRUE);
ATAPIReadBlks2(bd,0,buf,blk/spc,n/spc,TRUE);
FWBlks(f,buf,blk,n);
cnt-=n;
@@ -222,7 +222,7 @@ class CDualBuf
U8 *buf0,*buf1;
I64 in_buf,out_buf,cnt;
U8 *filename;
CBlkDev *CD_bdev;
CBlkDev *cd_bd;
};
U0 CDImageWriteTask(CDualBuf *d)
@@ -240,8 +240,8 @@ U0 CDImageWriteTask(CDualBuf *d)
n=COPY_BUF_BLKS;
else
n=cnt;
if (n>d->CD_bdev->max_writes)
n=d->CD_bdev->max_writes;
if (n>d->cd_bd->max_writes)
n=d->cd_bd->max_writes;
if (d->in_buf&1)
buf=d->buf1;
else
@@ -261,8 +261,8 @@ U0 CDImageWrite(U8 cd_drv_let,U8 *in_name=NULL,I64 media_type=MT_CD)
CDualBuf *d=CAlloc(sizeof(CDualBuf));
U8 *buf,*in_name2,*in_name3;
I64 i,n,spc,blk=0,cnt;
CPrt *p=Drv2Prt(cd_drv_let);
CBlkDev *bdev=p->bdev,*bdev2;
CDrv *dv=Let2Drv(cd_drv_let);
CBlkDev *bd=dv->bd,*bd2;
CTask *task;
Bool old_preempt;
CFile *f;
@@ -278,25 +278,25 @@ U0 CDImageWrite(U8 cd_drv_let,U8 *in_name=NULL,I64 media_type=MT_CD)
}
cnt=(FSize(f)+BLK_SIZE-1)>>BLK_SIZE_BITS;
FClose(f);
if (bdev->type!=BDT_ATAPI)
if (bd->type!=BDT_ATAPI)
throw('BlkDev');
bdev2=Drv2BlkDev(*in_name2);
while (bdev2->lock_fwding)
bdev2=bdev2->lock_fwding;
if ((bdev2->type==BDT_ATA || bdev2->type==BDT_ATAPI) &&
bdev2->base0==bdev->base0) {
bd2=Let2BlkDev(*in_name2);
while (bd2->lock_fwding)
bd2=bd2->lock_fwding; //If two blkdevs on same controller, use just one lock
if ((bd2->type==BDT_ATA || bd2->type==BDT_ATAPI) &&
bd2->base0==bd->base0) {
"Can't Burn CD on same ATA ctrller as File.\n\n";
throw('BlkDev');
}
bdev->flags|=BDF_READ_ONLY_OVERRIDE;
BlkDevInit(bdev);
spc=bdev->blk_size>>BLK_SIZE_BITS;
if (p->size<cnt)
p->size=cnt;
bd->flags|=BDF_READ_ONLY_OVERRIDE;
BlkDevInit(bd);
spc=bd->blk_size>>BLK_SIZE_BITS;
if (dv->size<cnt)
dv->size=cnt;
d->filename=in_name2;
d->CD_bdev=bdev;
d->cd_bd=bd;
d->buf0=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS);
d->buf1=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS);
d->cnt=cnt;
@@ -307,8 +307,8 @@ U0 CDImageWrite(U8 cd_drv_let,U8 *in_name=NULL,I64 media_type=MT_CD)
while (d->in_buf<=d->out_buf)
Yield;
BlkDevLock(bdev);
ATAPIWaitReady(bdev,0);
BlkDevLock(bd);
ATAPIWaitReady(bd,0);
progress1=0; progress1_max=cnt;
StrCpy(progress1_desc,"Writing");
@@ -317,43 +317,43 @@ U0 CDImageWrite(U8 cd_drv_let,U8 *in_name=NULL,I64 media_type=MT_CD)
n=COPY_BUF_BLKS;
else
n=cnt;
if (n>bdev->max_writes)
n=bdev->max_writes;
if (n>bd->max_writes)
n=bd->max_writes;
if (d->out_buf&1)
buf=d->buf1;
else
buf=d->buf0;
while (d->in_buf<=d->out_buf)
Yield;
ATAPIWriteBlks(bdev,buf,blk/spc,(n+spc-1)/spc);
ATAPIWriteBlks(bd,buf,blk/spc,(n+spc-1)/spc);
d->out_buf++;
cnt-=n;
blk+=n;
progress1+=n;
}
ATAPISync(bdev);
ATAPISync(bd);
progress1=0; progress1_max=2;
StrCpy(progress1_desc,"Closing");
for (i=0;i<2;i++) {
ATAPIClose(bdev,0x100,i); //Close tracks
ATAPIClose(bd,0x100,i); //Close tracks
progress1++;
}
ATAPISync(bdev);
ATAPISync(bd);
ATAPIClose(bdev,0x200); //close disk
ATAPISync(bdev);
ATAPIClose(bd,0x200); //close disk
ATAPISync(bd);
if (media_type==MT_DVD) {
ATAPIClose(bdev,0x300);
ATAPISync(bdev);
ATAPIClose(bd,0x300);
ATAPISync(bd);
}
*progress1_desc=0;
progress1=progress1_max=0;
bdev->flags&=~BDF_READ_ONLY_OVERRIDE;
BlkDevUnlock(bdev);
bd->flags&=~BDF_READ_ONLY_OVERRIDE;
BlkDevUnlock(bd);
Free(d->buf0);
Free(d->buf1);
Free(in_name2);
+39 -39
View File
@@ -22,15 +22,15 @@ CFile *FOpen(U8 *filename,U8 *flags,I64 cnt=0)
f->max_blk=MAX_I64;
f->file_cluster_num=INVALID_CLUSTER;
full_name=FileNameAbs(filename);
f->p=Drv2Prt(*full_name);
if (f->p->type==PT_REDSEA)
f->dv=Let2Drv(*full_name);
if (f->dv->type==DVT_REDSEA)
contiguous=TRUE;
if (contiguous) {
f->flags|=FF_CONTIGUOUS;
if (f->p->type!=PT_REDSEA && !(FileAttr(filename) & RS_ATTR_CONTIGUOUS))
if (f->dv->type!=DVT_REDSEA && !(FileAttr(filename) & RS_ATTR_CONTIGUOUS))
throw('File');
}
f->cluster_buf=CAlloc(f->p->spc<<BLK_SIZE_BITS);
f->cluster_buf=CAlloc(f->dv->spc<<BLK_SIZE_BITS);
if (StrOcc(flags,'w')) {
f->flags=f->flags|FF_WRITE|FF_NEEDS_WRITE;
if (StrOcc(flags,'+')) {
@@ -47,10 +47,10 @@ CFile *FOpen(U8 *filename,U8 *flags,I64 cnt=0)
if (fa=FileAccessNew(full_name)) {
StrCpy(f->de.name,fa->mask);
if (cnt>0) {//We pre-alloc the whole thing.
f->de.cluster=ClustersAlloc(f->p,0,
(cnt+f->p->spc-1)/f->p->spc,contiguous);
f->de.cluster=ClustersAlloc(f->dv,0,
(cnt+f->dv->spc-1)/f->dv->spc,contiguous);
f->de.size=cnt<<BLK_SIZE_BITS;
DirNew(fa->p,Fs->cur_dir,&f->de,TRUE);
DirNew(fa->dv,Fs->cur_dir,&f->de,TRUE);
f->flags&=~FF_NEW_FILE;
}
FileAccessDel(fa);
@@ -75,7 +75,7 @@ U0 FClose(CFile *f)
CFileAccess *fa;
if (f) {
if (f->flags & FF_BUF_DIRTY) {
WClusters(f->p,f->cluster_buf,f->cluster,1);
WClusters(f->dv,f->cluster_buf,f->cluster,1);
f->flags&=~FF_BUF_DIRTY;
}
if (f->flags & FF_NEEDS_WRITE) {
@@ -83,9 +83,9 @@ U0 FClose(CFile *f)
if (!(f->flags & FF_USE_OLD_DATETIME))
f->de.datetime=Now;
if (f->flags & FF_NEW_FILE)
DirNew(fa->p,Fs->cur_dir,&f->de,TRUE);
DirNew(fa->dv,Fs->cur_dir,&f->de,TRUE);
else
DirNew(fa->p,Fs->cur_dir,&f->de,FALSE);
DirNew(fa->dv,Fs->cur_dir,&f->de,FALSE);
FileAccessDel(fa);
} else
throw('File');
@@ -98,29 +98,29 @@ U0 FClose(CFile *f)
I64 FSetCluster(CFile *f,I64 c,I64 blk,Bool read)
{
CPrt *p=f->p;
CDrv *dv=f->dv;
I64 i;
if (f->cluster!=c) {
if (f->flags & FF_BUF_DIRTY) {
i=p->spc;
i=dv->spc;
if (f->max_blk!=MAX_I64) {
i=f->max_blk+1-f->file_cluster_num*p->spc;
if (i>p->spc)
i=p->spc;
i=f->max_blk+1-f->file_cluster_num*dv->spc;
if (i>dv->spc)
i=dv->spc;
}
WClustersBlks(p,f->cluster_buf,f->cluster,i);
WClustersBlks(dv,f->cluster_buf,f->cluster,i);
f->flags=f->flags & ~FF_BUF_DIRTY;
}
f->cluster=c;
f->file_cluster_num=blk/p->spc;
f->file_cluster_num=blk/dv->spc;
if (read) {
i=p->spc;
i=dv->spc;
if (f->max_blk!=MAX_I64) {
i=f->max_blk+1-f->file_cluster_num*p->spc;
if (i>p->spc)
i=p->spc;
i=f->max_blk+1-f->file_cluster_num*dv->spc;
if (i>dv->spc)
i=dv->spc;
}
c=RClustersBlks(p,f->cluster_buf,c,i);
c=RClustersBlks(dv,f->cluster_buf,c,i);
}
}
return c;
@@ -128,9 +128,9 @@ I64 FSetCluster(CFile *f,I64 c,I64 blk,Bool read)
Bool FRBlks(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1)
{//Read [nth,n+cnt) blks of file.
CPrt *p=f->p;
I64 spc=p->spc,i,j,c=f->de.cluster;
if (!f || !p) return FALSE;
CDrv *dv=f->dv;
I64 spc=dv->spc,i,j,c=f->de.cluster;
if (!f || !dv) return FALSE;
if (blk==FFB_NEXT_BLK)
blk=f->fblk_num;
if (blk+cnt-1>f->max_blk)
@@ -138,7 +138,7 @@ Bool FRBlks(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1)
if (cnt<=0) return TRUE;
if (f->flags & FF_CONTIGUOUS) {
RBlks(p,buf,Cluster2Blk(p,c)+blk,cnt);
RBlks(dv,buf,Cluster2Blk(dv,c)+blk,cnt);
blk+=cnt;
} else {
i=blk/spc;
@@ -147,7 +147,7 @@ Bool FRBlks(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1)
i-=f->file_cluster_num;
}
if (i>0)
c=ClusterNumNext(p,c,i);
c=ClusterNumNext(dv,c,i);
if (i=blk%spc) {
c=FSetCluster(f,c,blk,TRUE);
@@ -180,9 +180,9 @@ Bool FRBlks(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1)
Bool FWBlks(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1)
{//Write [nth,n+cnt) blks of file.
CPrt *p=f->p;
I64 spc=p->spc,i,j,c=f->de.cluster,c1;
if (!f || !p) return FALSE;
CDrv *dv=f->dv;
I64 spc=dv->spc,i,j,c=f->de.cluster,c1;
if (!f || !dv) return FALSE;
if (blk==FFB_NEXT_BLK)
blk=f->fblk_num;
if (blk+cnt-1>f->max_blk)
@@ -191,11 +191,11 @@ Bool FWBlks(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1)
return FALSE;
if (cnt<=0) return TRUE;
if (f->flags & FF_CONTIGUOUS) {
WBlks(p,buf,Cluster2Blk(p,c)+blk,cnt);
WBlks(dv,buf,Cluster2Blk(dv,c)+blk,cnt);
blk+=cnt;
} else {
if (!c) {
c=ClustersAlloc(p,0,1,FALSE);
c=ClustersAlloc(dv,0,1,FALSE);
f->file_cluster_num=0;
f->cluster=c;
f->de.cluster=c;
@@ -208,11 +208,11 @@ Bool FWBlks(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1)
}
while (i>0) {
c1=c;
c=ClusterNumNext(p,c1,1);
c=ClusterNumNext(dv,c1,1);
if (c==INVALID_CLUSTER) {
c=ClustersAlloc(p,c1,i,FALSE);
c=ClustersAlloc(dv,c1,i,FALSE);
if (i>1)
c=ClusterNumNext(p,c,i-1);
c=ClusterNumNext(dv,c,i-1);
break;
} else
i--;
@@ -231,9 +231,9 @@ Bool FWBlks(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1)
blk+=j;
if (cnt>0) {
c1=c;
c=ClusterNumNext(p,c1,1);
c=ClusterNumNext(dv,c1,1);
if (c==INVALID_CLUSTER)
c=ClustersAlloc(p,c1,1,FALSE);
c=ClustersAlloc(dv,c1,1,FALSE);
}
}
while (cnt>=spc) {
@@ -245,9 +245,9 @@ Bool FWBlks(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1)
blk+=spc;
if (cnt>0) {
c1=c;
c=ClusterNumNext(p,c1,1);
c=ClusterNumNext(dv,c1,1);
if (c==INVALID_CLUSTER)
c=ClustersAlloc(p,c1,1,FALSE);
c=ClustersAlloc(dv,c1,1,FALSE);
}
}
if (cnt>0) {
+12 -12
View File
@@ -23,7 +23,7 @@ U0 DskCacheInit(I64 size_in_U8s)
tempc=dsk.cache_base+i;
QueIns(tempc,dsk.cache_ctrl->last_lru);
tempc->next_hash=tempc->last_hash=tempc;
tempc->p=NULL;
tempc->dv=NULL;
tempc->blk=0;
}
@@ -60,30 +60,30 @@ U0 DskCacheQueIns(CCacheBlk *tempc)
temp_l->next_hash=temp_n->last_hash=tempc;
}
CCacheBlk *DskCacheFind(CPrt *p,I64 blk)
CCacheBlk *DskCacheFind(CDrv *dv,I64 blk)
{
CCacheBlk *tempc,*tempc1=DskCacheHash(blk);
tempc=tempc1->next_hash;
while (tempc!=tempc1) {
if (tempc->p==p && tempc->blk==blk)
if (tempc->dv==dv && tempc->blk==blk)
return tempc;
tempc=tempc->next_hash;
}
return NULL;
}
U0 DskCacheAdd(CPrt *p,U8 *buf, I64 blk, I64 cnt)
U0 DskCacheAdd(CDrv *dv,U8 *buf, I64 blk, I64 cnt)
{
CCacheBlk *tempc;
if (dsk.cache_base) {
while (LBts(&sys_semas[SYS_SEMA_DSK_CACHE],0))
Yield;
while (cnt-->0) {
if (!(tempc=DskCacheFind(p,blk)))
if (!(tempc=DskCacheFind(dv,blk)))
tempc=dsk.cache_ctrl->next_lru;
DskCacheQueRem(tempc);
MemCpy(&tempc->body,buf,BLK_SIZE);
tempc->p=p;
tempc->dv=dv;
tempc->blk=blk;
DskCacheQueIns(tempc);
blk++;
@@ -93,7 +93,7 @@ U0 DskCacheAdd(CPrt *p,U8 *buf, I64 blk, I64 cnt)
}
}
U0 DskCacheInvalidate2(CPrt *p)
U0 DskCacheInvalidate2(CDrv *dv)
{
CCacheBlk *tempc,*tempc1;
if (dsk.cache_base) {
@@ -102,9 +102,9 @@ U0 DskCacheInvalidate2(CPrt *p)
tempc=dsk.cache_ctrl->last_lru;
while (tempc!=dsk.cache_ctrl) {
tempc1=tempc->last_lru;
if (tempc->p==p) {
if (tempc->dv==dv) {
DskCacheQueRem(tempc);
tempc->p=NULL;
tempc->dv=NULL;
tempc->blk=0;
tempc->next_hash=tempc->last_hash=tempc;
QueIns(tempc,dsk.cache_ctrl->last_lru);
@@ -115,7 +115,7 @@ U0 DskCacheInvalidate2(CPrt *p)
}
}
U0 RCache(CPrt *p,U8 **_buf, I64 *_blk, I64 *_cnt)
U0 RCache(CDrv *dv,U8 **_buf, I64 *_blk, I64 *_cnt)
{
CCacheBlk *tempc;
if (dsk.cache_base) {
@@ -123,7 +123,7 @@ U0 RCache(CPrt *p,U8 **_buf, I64 *_blk, I64 *_cnt)
Yield;
//fetch leading blks from cache
while (*_cnt>0) {
if (tempc=DskCacheFind(p,*_blk)) {
if (tempc=DskCacheFind(dv,*_blk)) {
MemCpy(*_buf,&tempc->body,BLK_SIZE);
*_cnt-=1;
*_buf+=BLK_SIZE;
@@ -133,7 +133,7 @@ U0 RCache(CPrt *p,U8 **_buf, I64 *_blk, I64 *_cnt)
}
//fetch trailing blks from cache
while (*_cnt>0) {
if (tempc=DskCacheFind(p,*_blk+*_cnt-1)) {
if (tempc=DskCacheFind(dv,*_blk+*_cnt-1)) {
MemCpy(*_buf+(*_cnt-1)<<BLK_SIZE_BITS,&tempc->body,BLK_SIZE);
*_cnt-=1;
} else
+16 -17
View File
@@ -1,11 +1,11 @@
Bool DirNew(CPrt *p,U8 *cur_dir,CDirEntry *tempde,Bool free_old_chain=TRUE)
Bool DirNew(CDrv *dv,U8 *cur_dir,CDirEntry *tempde,Bool free_old_chain=TRUE)
{//Makes a directory entry in the directory from a $LK,"CDirEntry",A="MN:CDirEntry"$ node.
switch (p->type) {
case PT_REDSEA:
return RedSeaFSDirNew(p,cur_dir,tempde,free_old_chain);
case PT_FAT32:
return FAT32DirNew(p,cur_dir,tempde,free_old_chain);
case PT_ISO9660:
switch (dv->type) {
case DVT_REDSEA:
return RedSeaDirNew(dv,cur_dir,tempde,free_old_chain);
case DVT_FAT32:
return FAT32DirNew(dv,cur_dir,tempde,free_old_chain);
case DVT_ISO9660:
PrintErr("Not Writable\n");
return FALSE;
default:
@@ -166,17 +166,17 @@ CDirEntry *DirFilesFlatten(CDirEntry *tempde,CDirEntry **_result,I64 fuf_flags)
CDirEntry *SysFilesFind(U8 *files_find_mask,I64 fuf_flags)
{
CPrt *p=Fs->cur_prt;
CDrv *dv=Fs->cur_dv;
CDirEntry *result=NULL;
PrtChk(p);
switch (p->type) {
case PT_REDSEA:
result=RedSeaFSFilesFind(files_find_mask,fuf_flags);
DrvChk(dv);
switch (dv->type) {
case DVT_REDSEA:
result=RedSeaFilesFind(files_find_mask,fuf_flags);
break;
case PT_FAT32:
case DVT_FAT32:
result=FAT32FilesFind(files_find_mask,fuf_flags);
break;
case PT_ISO9660:
case DVT_ISO9660:
result=ISO1FilesFind(files_find_mask,fuf_flags);
break;
default:
@@ -194,7 +194,7 @@ CDirEntry *SysFilesFind(U8 *files_find_mask,I64 fuf_flags)
}
U0 PutFileLink(U8 *filename,I64 line=0,Bool plain_text=FALSE)
{//Put $LK,"DolDoc",A="FI:::/Doc/DolDocOverview.TXT.Z"$ file,line link to StdOut, $LK,"DocPut",A="MN:DocPut"$.
{//Put $LK,"DolDoc",A="FI:::/Doc/DolDocOverview.TXT"$ file,line link to StdOut, $LK,"DocPut",A="MN:DocPut"$.
U8 *buf;
if (!filename) return;
if (IsRaw) {
@@ -228,7 +228,7 @@ U0 PutFileLink(U8 *filename,I64 line=0,Bool plain_text=FALSE)
}
U0 PutDirLink(U8 *dirname)
{//Put $LK,"DolDoc",A="FI:::/Doc/DolDocOverview.TXT.Z"$ dir macro to StdOut, $LK,"DocPut",A="MN:DocPut"$.
{//Put $LK,"DolDoc",A="FI:::/Doc/DolDocOverview.TXT"$ dir macro to StdOut, $LK,"DocPut",A="MN:DocPut"$.
U8 *buf;
if (!dirname) return;
if (IsRaw)
@@ -284,7 +284,6 @@ I64 Dir2(U8 *files_find_mask,I64 fuf_flags,Bool full)
PutDirLink(tempde1->name);
else
PutFileLink(tempde1->name);
'\n';
DirEntryDel(tempde1);
tempde1=tempde2;
+80 -89
View File
@@ -79,170 +79,161 @@ Bool FilesFindMatch(U8 *test_filename,U8 *files_find_mask,I64 fuf_flags=0)
return result;
}
U0 PrtChk(CPrt *p)
{//Check for valid partition. Throw exception.
if (!p || p->pt_signature!=PRT_SIGNATURE_VAL)
throw('Prt');
U0 DrvChk(CDrv *dv)
{//Check for valid drv. Throw exception.
if (!dv || dv->dv_signature!=DRV_SIGNATURE_VAL)
throw('Drv');
}
U8 Prt2Drv(CPrt *p=NULL)
{//Prt ptr to Drv letter.
if (!p)
p=Fs->cur_prt;
PrtChk(p);
return p->drv_let;
U8 Drv2Let(CDrv *dv=NULL)
{//Drv ptr to Drv letter.
if (!dv)
dv=Fs->cur_dv;
DrvChk(dv);
return dv->drv_let;
}
CPrt *Drv2Prt(U8 drv_let=0)
{//Drv letter to Prt ptr.
CPrt *p;
CDrv *Let2Drv(U8 drv_let=0)
{//Drv letter to Drv ptr.
CDrv *dv;
if (!drv_let)
p=Fs->cur_prt;
dv=Fs->cur_dv;
else {
if (drv_let==':')
drv_let=*sys_acct;
drv_let=dsk.boot_drv_let;
drv_let=ToUpper(drv_let);
if (!('A'<=drv_let<='Z'))
throw('Prt');
p=dsk.drv_to_prt[drv_let-'A'];
throw('Drv');
dv=dsk.let_to_drv[drv_let-'A'];
}
PrtChk(p);
return p;
DrvChk(dv);
return dv;
}
U0 BlkDevChk(CBlkDev *bdev)
U0 BlkDevChk(CBlkDev *bd)
{//Check for valid BlkDev. Throw exception.
if (!bdev || bdev->bd_signature!=BD_SIGNATURE_VAL ||
!(BDT_NULL<bdev->type<BDT_NUM_TYPES))
if (!bd || bd->bd_signature!=BD_SIGNATURE_VAL ||
!(BDT_NULL<bd->type<BDT_NUM_TYPES))
throw('BlkDev');
}
CBlkDev *Drv2BlkDev(U8 drv_let=0)
CBlkDev *Let2BlkDev(U8 drv_let=0)
{//Drv letter to BlkDev ptr.
CPrt *p=Drv2Prt(drv_let);
CBlkDev *bdev=p->bdev;
BlkDevChk(bdev);
return bdev;
CDrv *dv=Let2Drv(drv_let);
CBlkDev *bd=dv->bd;
BlkDevChk(bd);
return bd;
}
Bool IsDrvWritable(U8 drv_let=0)
{//Is drive writable?
CBlkDev *bdev=Drv2BlkDev(drv_let);
if (bdev->flags & BDF_READ_ONLY)
CBlkDev *bd=Let2BlkDev(drv_let);
if (bd->flags & BDF_READ_ONLY)
return FALSE;
else
return TRUE;
}
U8 *CurDir(CTask *task=NULL,CTask *mem_task=NULL)
{//MAlloc copy of cur dir with partition letter.
{//MAlloc copy of cur dir with drv letter.
U8 *st;
if (!task) task=Fs;
if (!task->cur_dir)
return NULL;
st=MAlloc(StrLen(task->cur_dir)+3,mem_task);
*st=Prt2Drv;
*st=Drv2Let(task->cur_dv);
st[1]=':';
StrCpy(st+2,task->cur_dir);
return st;
}
U8 *DirNameAbs(U8 *_dirname)
{//MAlloc absolute dir string with partition letter.
{//MAlloc absolute dir string with drv letter.
I64 maxlen;
U8 drv[3],*cur_dir,*buf2,*buf3,*buf,*dirname,*temp_name;
U8 drv[3],*result,*buf,*buf2,*buf3,*buf4,*dirname,*free_dirname;
if (!Fs->cur_dir || !*Fs->cur_dir)
return StrNew(_dirname);
dirname=MStrUtil(_dirname,SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
temp_name=dirname;
*drv=Prt2Drv;
free_dirname=dirname=MStrUtil(_dirname,
SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
*drv=Drv2Let;
drv[1]=':';
drv[2]=0;
if (*dirname && dirname[1]==':') {
if (*dirname==':')
*drv=*sys_acct;
*drv=dsk.boot_drv_let;
else
*drv=*dirname;
dirname=dirname+2;
cur_dir=StrNew("/");
buf=StrNew("/");
} else
cur_dir=StrNew(Fs->cur_dir);
buf=StrNew(Fs->cur_dir);
if (*dirname=='/') {
Free(cur_dir);
cur_dir=StrNew("/");
Free(buf);
buf=StrNew("/");
dirname++;
}
buf2=StrNew(dirname);
maxlen=StrLen(cur_dir)+1+StrLen(buf2)+1;
maxlen=StrLen(buf)+1+StrLen(buf2)+1;
buf3=MAlloc(maxlen);
buf =MAlloc(maxlen);
StrCpy(buf3,cur_dir);
buf4=MAlloc(maxlen);
StrCpy(buf3,buf);
while (*buf2) {
StrFirstRem(buf2,"/",buf);
if (!*buf)
StrFirstRem(buf2,"/",buf4);
if (!*buf4)
StrCpy(buf3,"/");
else if (!StrCmp(buf,"..")) {
else if (!StrCmp(buf4,"..")) {
StrLastRem(buf3,"/");
if (!*buf3)
StrCpy(buf3,"/");
} else if (!StrCmp(buf,".")) {
} else if (!StrCmp(buf4,".")) {
;
} else if (*buf) {
if (!StrCmp(buf,"HOME")) {
Free(buf3);
buf3=MAlloc(maxlen+StrLen(sys_acct));
StrCpy(buf3,sys_acct+2);
*drv=*sys_acct;
} else {
if (StrCmp(buf3,"/"))
CatPrint(buf3,"/");
CatPrint(buf3,buf);
}
} else if (*buf4) {
if (StrCmp(buf3,"/"))
CatPrint(buf3,"/");
CatPrint(buf3,buf4);
}
}
Free(cur_dir);
cur_dir=MAlloc(StrLen(buf3)+3);
StrCpy(cur_dir,drv);
StrCpy(cur_dir+2,buf3);
Free(buf);
result=MAlloc(StrLen(buf3)+3);
StrCpy(result,drv);
StrCpy(result+2,buf3);
Free(buf2);
Free(buf3);
Free(temp_name);
return cur_dir;
Free(buf4);
Free(free_dirname);
return result;
}
U8 *FileNameAbs(U8 *_filename,I64 fuf_flags=0)
{//Absolute filename. Accepts $LK,"FUF_Z_OR_NOT_Z",A="MN:FUF_Z_OR_NOT_Z"$, $LK,"FUF_SCAN_PARENTS",A="MN:FUF_SCAN_PARENTS"$.
U8 *buf,*buf2,*buf3,*filename,*temp_name,*temp_buf;
U8 *result,*filename,*buf,*buf_file,*buf_dir,*free_filename,*free_buf;
CDirEntry de;
filename=MStrUtil(_filename,SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
temp_name=filename;
buf=StrNew(filename);
temp_buf=buf;
free_filename=filename=MStrUtil(_filename,
SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
free_buf=buf=StrNew(filename);
if (*buf && buf[1]==':') {
buf+=2;
filename+=2;
}
buf2=MAlloc(StrLen(temp_name)+1);
StrLastRem(buf,"/",buf2);
buf_file=MAlloc(StrLen(free_filename)+1);
StrLastRem(buf,"/",buf_file);
if (*filename=='/' && !*buf)
StrCpy(buf,"/");
buf3=DirNameAbs(temp_buf);
Free(temp_buf);
buf=MAlloc(StrLen(buf3)+1+StrLen(buf2)+1);
StrCpy(buf,buf3);
if (buf[StrLen(buf)-1]!='/')
CatPrint(buf,"/");
CatPrint(buf,buf2);
Free(buf2);
Free(buf3);
Free(temp_name);
if (fuf_flags&&FileFind(buf,&de,fuf_flags|FUF_JUST_FILES)) {
Free(buf);
buf=de.full_name;
buf_dir=DirNameAbs(free_buf);
Free(free_buf);
result=MAlloc(StrLen(buf_dir)+1+StrLen(buf_file)+1);
StrCpy(result,buf_dir);
if (result[StrLen(result)-1]!='/')
CatPrint(result,"/");
CatPrint(result,buf_file);
Free(buf_file);
Free(buf_dir);
Free(free_filename);
if (fuf_flags&&FileFind(result,&de,fuf_flags|FUF_JUST_FILES)) {
Free(result);
result=de.full_name;
}
return buf;
return result;
}
U8 *ChgExt(U8 *filename,U8 *extension)
@@ -311,7 +302,7 @@ U8 *DirFile(U8 *dirname,U8 *name=NULL,U8 *_extension=NULL)
{/*Strips file from dirname, scans for file upward until found or
returns default.
("/Kernel/Hash1a.CPP.Z",NULL,NULL) returns "D:/Kernel"
("/Kernel/KHashA.CPP.Z",NULL,NULL) returns "D:/Kernel"
("/Kernel",NULL,"PRJ.Z") returns "D:/Kernel/Kernel.PRJ.Z"
("/Kernel/Dsk",NULL,"PRJ.Z") returns "D:/Kernel/Kernel.PRJ.Z"
("/Apps/Psalmody","Load","CPP.Z") returns "D:/Apps/Psalmody/Load.CPP.Z"
@@ -371,5 +362,5 @@ U8 *ToggleZorNotZ(U8 *name)
U8 *FileNameTempTxt()
{//Make pretty-safe temp filename in home dir.
return MStrPrint("HOME/SysTemp%X.TXT.Z",GetTSC>>8&0xFFFFFFFF);
return MStrPrint("::/Home/SysTemp%X.TXT.Z",GetTSC>>8&0xFFFFFFFF);
}
+212 -212
View File
@@ -19,42 +19,42 @@ CDate Dos2CDate(U16 t,U16 d)
return Struct2Date(&ds)-local_time_offset;
}
U0 FAT32PrtInit(CPrt *p)
U0 FAT32DrvInit(CDrv *dv)
{
CFAT32Boot br32;
Bool unlock;
try {
unlock=PrtLock(p);
p->type=PT_FAT32;
RBlks(p,&br32,p->offset,1);
p->file_system_info_sect=p->offset+br32.file_system_info_sect;
p->map1=p->offset+br32.reserved_sects;
p->map2=p->map1+br32.sects_per_fat;
p->data=p->map2+br32.sects_per_fat-2*br32.sects_per_cluster; //Starts at Cluster 2
p->spc=br32.sects_per_cluster;
p->root_cluster=br32.root_cluster;
MapBufAlloc(p,1);
Free(p->fis);
p->fis=AMAlloc(BLK_SIZE);
RBlks(p,p->fis,p->file_system_info_sect,1);
unlock=DrvLock(dv);
dv->type=DVT_FAT32;
RBlks(dv,&br32,dv->base_offset,1);
dv->file_system_info_sect=dv->base_offset+br32.file_system_info_sect;
dv->map1=dv->base_offset+br32.reserved_sects;
dv->map2=dv->map1+br32.sects_per_fat;
dv->data_area=dv->map2+br32.sects_per_fat-2*br32.sects_per_cluster; //Starts at Cluster 2
dv->spc=br32.sects_per_cluster;
dv->root_cluster=br32.root_cluster;
DrvMapBlkAlloc(dv);
Free(dv->fis);
dv->fis=AMAlloc(BLK_SIZE);
RBlks(dv,dv->fis,dv->file_system_info_sect,1);
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
} catch
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
}
Bool FAT32DrvValidate(U8 drv_let)
{
CPrt *p;
CDrv *dv;
CFAT32Boot br;
Bool result=FALSE;
try {
p=Drv2Prt(drv_let);
if (p->type==PT_FAT32 &&
RBlks(p,&br,p->offset,1) &&
dv=Let2Drv(drv_let);
if (dv->type==DVT_FAT32 &&
RBlks(dv,&br,dv->base_offset,1) &&
br.signature==0xAA55 &&
br.sects==p->size)
br.sects==dv->size)
result=TRUE;
} catch
Fs->catch_except=TRUE;
@@ -65,28 +65,28 @@ U0 FAT32Fmt(U8 drv_let,Bool quick=TRUE)
{
CFAT32Boot *br=CAlloc(BLK_SIZE);
CFAT32FileInfoSect *fis=CAlloc(BLK_SIZE);
CPrt *p=Drv2Prt(drv_let);
CDrv *dv=Let2Drv(drv_let);
I64 i,l;
try {
PrtLock(p);
SetDrvType(drv_let,PT_FAT32);
p->type=PT_FAT32;
DrvLock(dv);
DrvTypeSet(drv_let,DVT_FAT32);
dv->type=DVT_FAT32;
br->jump_and_nop[0]=OC_JMP_REL8;
br->jump_and_nop[1]=offset(CFAT32Boot.code)-2;
br->jump_and_nop[2]=OC_NOP;
MemCpy(br->oem_name,"MSWIN4.1",8);
br->oem_name[0](I64)='MSWIN4.1';
br->bytes_per_sect=BLK_SIZE;
if (p->size<= 500000)
if (dv->size<= 500000)
br->sects_per_cluster=1;
else if (p->size<=2000000)
else if (dv->size<=2000000)
br->sects_per_cluster=2;
else if (p->size<=6000000)
else if (dv->size<=6000000)
br->sects_per_cluster=4;
else if (p->size<=12000000)
else if (dv->size<=12000000)
br->sects_per_cluster=8;
else if (p->size<=33000000)
else if (dv->size<=33000000)
br->sects_per_cluster=16;
else if (p->size<=67000000)
else if (dv->size<=67000000)
br->sects_per_cluster=32;
else
br->sects_per_cluster=64;
@@ -94,7 +94,7 @@ U0 FAT32Fmt(U8 drv_let,Bool quick=TRUE)
br->reserved_sects=32;
br->copies_of_fat=2;
br->media_desc=0xF8;
br->sects=p->size;
br->sects=dv->size;
l=(br->sects/br->sects_per_cluster)>>(BLK_SIZE_BITS-2)+1;
br->sects_per_fat=l;
br->root_cluster=2;
@@ -103,30 +103,30 @@ U0 FAT32Fmt(U8 drv_let,Bool quick=TRUE)
br->ext_signature=0x29;
br->serial_num=RandU32;
MemCpy(br->vol_name,"NO NAME ",11);
MemCpy(br->fat_name,"FAT32 ",8);
br->fat_name[0](I64)='FAT32 ';
br->signature=0xAA55;
fis->signature1=0x41615252;
fis->signature2=0x61417272;
fis->signature1='RRaA';
fis->signature2='rrAa';
fis->free_clusters=-1;
fis->most_recently_allocated=0;
fis->most_recently_alloced=0;
fis->signature3=0xAA550000;
if (quick)
i=br->reserved_sects+2*l+4*br->sects_per_cluster;
else
i=p->size;
WZeroBlks(p,p->offset,i);
i=dv->size;
WZeroBlks(dv,dv->base_offset,i);
WBlks(p,fis,p->offset+br->file_system_info_sect,1);
WBlks(p,br,p->offset,1);
FAT32PrtInit(p);
ClustersAlloc(p,0,1,FALSE); //Allocate #1
br->root_cluster=ClustersAlloc(p,0,1,FALSE);
WBlks(p,br,p->offset,1);
FAT32PrtInit(p);
PrtUnlock(p);
WBlks(dv,fis,dv->base_offset+br->file_system_info_sect,1);
WBlks(dv,br,dv->base_offset,1);
FAT32DrvInit(dv);
ClustersAlloc(dv,0,1,FALSE); //Alloc #1
br->root_cluster=ClustersAlloc(dv,0,1,FALSE);
WBlks(dv,br,dv->base_offset,1);
FAT32DrvInit(dv);
DrvUnlock(dv);
} catch
PrtUnlock(p);
DrvUnlock(dv);
Free(br);
Free(fis);
}
@@ -296,7 +296,7 @@ Bool FAT32DirFill(CFAT32DirEntry *de,CDirEntry *tempde,I64 *_de_cnt=NULL)
return result;
}
Bool FAT32FileFind(CPrt *p,I64 cur_dir_cluster,U8 *name,CDirEntry *_result,I64 fuf_flags=0)
Bool FAT32FileFind(CDrv *dv,I64 cur_dir_cluster,U8 *name,CDirEntry *_result,I64 fuf_flags=0)
{//$LK,"FUF_JUST_DIRS",A="MN:FUF_JUST_DIRS"$, $LK,"FUF_JUST_FILES",A="MN:FUF_JUST_FILES"$
Bool result=FALSE,unlock;
CFAT32DirEntry *buf;
@@ -307,17 +307,17 @@ Bool FAT32FileFind(CPrt *p,I64 cur_dir_cluster,U8 *name,CDirEntry *_result,I64 f
throw('FUF');
MemSet(_result,0,sizeof(CDirEntry));
MemSet(&long_name,0,sizeof(CDirEntry));
PrtChk(p);
if (p->type!=PT_FAT32)
PrintErr("Not FAT32 Partition\n");
DrvChk(dv);
if (dv->type!=DVT_FAT32)
PrintErr("Not FAT32 Drv\n");
else if (!CFileNameTo(dname,name))
PrintErr("Invalid FileName.\n");
else
try {
unlock=PrtLock(p);
buf=MAlloc(BLK_SIZE*p->spc);
entries_per_cluster=p->spc<<FAT32_ENTRIES_BITS;
RClusters(p,buf,cur_dir_cluster,1);
unlock=DrvLock(dv);
buf=MAlloc(BLK_SIZE*dv->spc);
entries_per_cluster=dv->spc<<FAT32_ENTRIES_BITS;
RClusters(dv,buf,cur_dir_cluster,1);
cur_dir_entry=0;
while (ch=*buf[cur_dir_entry].name) {
attr=buf[cur_dir_entry].attr;
@@ -331,11 +331,11 @@ Bool FAT32FileFind(CPrt *p,I64 cur_dir_cluster,U8 *name,CDirEntry *_result,I64 f
else
MemSet(_result,0,sizeof(CDirEntry));
if (!(fuf_flags&FUF_JUST_DIRS && !(attr & RS_ATTR_DIR)) &&
!(fuf_flags&FUF_JUST_FILES && attr & RS_ATTR_DIR) &&
FAT32CDirFill(_result,&buf[cur_dir_entry]) &&
!StrCmp(dname,_result->name)) {
result=TRUE;
goto exit_this;
!(fuf_flags&FUF_JUST_FILES && attr & RS_ATTR_DIR) &&
FAT32CDirFill(_result,&buf[cur_dir_entry]) &&
!StrCmp(dname,_result->name)) {
result=TRUE;
goto fff_done;
}
}
MemSet(&long_name,0,sizeof(CDirEntry));
@@ -343,64 +343,64 @@ Bool FAT32FileFind(CPrt *p,I64 cur_dir_cluster,U8 *name,CDirEntry *_result,I64 f
} else
MemSet(&long_name,0,sizeof(CDirEntry));
if (++cur_dir_entry==entries_per_cluster) {
cur_dir_cluster=ClusterNumNext(p,cur_dir_cluster);
cur_dir_cluster=ClusterNumNext(dv,cur_dir_cluster);
if (!(0<cur_dir_cluster<0x0FFFFFF8))
break;
else {
RClusters(p,buf,cur_dir_cluster,1);
RClusters(dv,buf,cur_dir_cluster,1);
cur_dir_entry=0;
}
}
}
MemSet(_result,0,sizeof(CDirEntry));
exit_this:
fff_done:
Free(buf);
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
} catch
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
return result;
}
U8 *FAT32FileRead(CPrt *p,U8 *cur_dir,U8 *filename,I64 *_size,I64 *_attr)
U8 *FAT32FileRead(CDrv *dv,U8 *cur_dir,U8 *filename,I64 *_size,I64 *_attr)
{
U8 *buf=NULL;
CDirEntry de;
I64 c,blk_cnt,cur_dir_cluster;
PrtChk(p);
DrvChk(dv);
*_size=0;
*_attr=0;
if (p->type!=PT_FAT32)
PrintErr("Not FAT32 Partition\n");
if (dv->type!=DVT_FAT32)
PrintErr("Not FAT32 Drv\n");
else
try {
PrtLock(p);
cur_dir_cluster=Name2DirCluster(p,cur_dir);
if (FAT32FileFind(p,cur_dir_cluster,filename,&de,FUF_JUST_FILES)) {
DrvLock(dv);
cur_dir_cluster=Name2DirCluster(dv,cur_dir);
if (FAT32FileFind(dv,cur_dir_cluster,filename,&de,FUF_JUST_FILES)) {
blk_cnt=(de.size+BLK_SIZE-1)>>BLK_SIZE_BITS;
buf=MAlloc(blk_cnt<<BLK_SIZE_BITS+1);
c=de.cluster;
if (!(0<c<0x0FFFFFF8))
c=0x0FFFFFFF;
else
c=RClustersBlks(p,buf,c,blk_cnt);
c=RClustersBlks(dv,buf,c,blk_cnt);
buf[de.size]=0; //Terminate
*_size=de.size;
*_attr=FileAttr(de.name,de.attr);
}
PrtUnlock(p);
DrvUnlock(dv);
} catch
PrtUnlock(p);
DrvUnlock(dv);
return buf;
}
Bool FAT32Cd(U8 *name,I64 cur_dir_cluster)
{
CDirEntry de;
if (Fs->cur_prt->type!=PT_FAT32)
PrintErr("Not FAT32 Partition\n");
else if (FAT32FileFind(Fs->cur_prt,cur_dir_cluster,name,&de,FUF_JUST_DIRS))
if (Fs->cur_dv->type!=DVT_FAT32)
PrintErr("Not FAT32 Drv\n");
else if (FAT32FileFind(Fs->cur_dv,cur_dir_cluster,name,&de,FUF_JUST_DIRS))
return TRUE;
else {
"%s ",name;
@@ -409,50 +409,50 @@ Bool FAT32Cd(U8 *name,I64 cur_dir_cluster)
return FALSE;
}
U0 FAT32FreeClusters(CPrt *p,I64 c)
U0 FAT32FreeClusters(CDrv *dv,I64 c)
{
I64 next,saved_c=c;
Bool unlock,unlock_break;
PrtChk(p);
DrvChk(dv);
if (!(0<c<0x0FFFFFF8)) return;
if (p->type!=PT_FAT32)
PrintErr("Not FAT32 Partition\n");
if (dv->type!=DVT_FAT32)
PrintErr("Not FAT32 Drv\n");
else
try {
unlock_break=BreakLock;
unlock=PrtLock(p);
CleanMAPBuf(p);
unlock=DrvLock(dv);
DrvMapBlkClean(dv);
do {
SetFSBuf(p,c,0);
next=p->cur_map_blk[c&(BLK_SIZE/4-1)];
p->cur_map_blk[c&(BLK_SIZE/4-1)]=0;
LBts(p->buffered_map_dirty_bits,0);
DrvMapBlkSet(dv,c,0);
next=dv->cur_map_blk[c&(BLK_SIZE/4-1)];
dv->cur_map_blk[c&(BLK_SIZE/4-1)]=0;
LBts(&dv->map_blk_dirty,0);
c=next;
} while (0<c<0x0FFFFFF8);
CleanMAPBuf(p,0);
DrvMapBlkClean(dv,0);
c=saved_c;
do {
SetFSBuf(p,c,1);
next=p->cur_map_blk[c&(BLK_SIZE/4-1)];
p->cur_map_blk[c&(BLK_SIZE/4-1)]=0;
LBts(p->buffered_map_dirty_bits,0);
DrvMapBlkSet(dv,c,1);
next=dv->cur_map_blk[c&(BLK_SIZE/4-1)];
dv->cur_map_blk[c&(BLK_SIZE/4-1)]=0;
LBts(&dv->map_blk_dirty,0);
c=next;
} while (0<c<0x0FFFFFF8);
CleanMAPBuf(p,1);
DrvMapBlkClean(dv,1);
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
if (unlock_break)
BreakUnlock;
} catch {
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
if (unlock_break)
BreakUnlock;
}
}
I64 FAT32AllocClusters(CPrt *p,I64 c,I64 cnt)
I64 FAT32AllocClusters(CDrv *dv,I64 c,I64 cnt)
{
Bool wrap_around=FALSE,unlock,unlock_break;
I64 first=INVALID_CLUSTER,j,l;
@@ -460,57 +460,57 @@ I64 FAT32AllocClusters(CPrt *p,I64 c,I64 cnt)
if (cnt<=0) return 0x0FFFFFFF;
try {
unlock_break=BreakLock;
unlock=PrtLock(p);
l=(p->size+p->offset-p->data)/p->spc-1;
j=p->fis->most_recently_allocated;
unlock=DrvLock(dv);
l=(dv->size+dv->base_offset-dv->data_area)/dv->spc-1;
j=dv->fis->most_recently_alloced;
while (cnt-->0) {
while (TRUE) {
j++;
if (j<1) j=1;
if (j>=l) {
if (wrap_around)
Dbg;
throw('Drv');
j=1;
wrap_around=TRUE;
}
SetFSBuf(p,j);
if (!p->cur_map_blk[j&(BLK_SIZE/4-1)])
DrvMapBlkSet(dv,j);
if (!dv->cur_map_blk[j&(BLK_SIZE/4-1)])
break;
}
if (!(0<first<0x0FFFFFF8))
first=j;
if (0<c<l) {
SetFSBuf(p,c);
p->cur_map_blk[c&(BLK_SIZE/4-1)]=j;
LBts(p->buffered_map_dirty_bits,0);
DrvMapBlkSet(dv,c);
dv->cur_map_blk[c&(BLK_SIZE/4-1)]=j;
LBts(&dv->map_blk_dirty,0);
}
c=j;
}
if (0<c<l) {
SetFSBuf(p,c);
p->cur_map_blk[c&(BLK_SIZE/4-1)]=0x0FFFFFFF;
LBts(p->buffered_map_dirty_bits,0);
DrvMapBlkSet(dv,c);
dv->cur_map_blk[c&(BLK_SIZE/4-1)]=0x0FFFFFFF;
LBts(&dv->map_blk_dirty,0);
}
CleanMAPBuf(p);
DrvMapBlkClean(dv);
p->fis->most_recently_allocated=j;
p->fis->free_clusters=-1;
WBlks(p,p->fis,p->file_system_info_sect,1);
dv->fis->most_recently_alloced=j;
dv->fis->free_clusters=-1;
WBlks(dv,dv->fis,dv->file_system_info_sect,1);
} catch {
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
if (unlock_break)
BreakUnlock;
}
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
if (unlock_break)
BreakUnlock;
return first;
}
I64 FAT32AllocContiguousClusters(CPrt *p,I64 cnt)
I64 FAT32AllocContiguousClusters(CDrv *dv,I64 cnt)
{
I64 i,first=1;
Bool cont,unlock,unlock_break;
@@ -518,16 +518,16 @@ I64 FAT32AllocContiguousClusters(CPrt *p,I64 cnt)
if (cnt<=0) return 0x0FFFFFFF;
try {
unlock_break=BreakLock;
unlock=PrtLock(p);
unlock=DrvLock(dv);
while (TRUE) {
first++;
i=0;
cont=TRUE;
while (cont && i<cnt) {
if ((first+i+1)*p->spc+p->data>p->size+p->offset)
Dbg;
SetFSBuf(p,first+i);
if (p->cur_map_blk[(first+i)&(BLK_SIZE/4-1)])
if ((first+i+1)*dv->spc+dv->data_area>dv->size+dv->base_offset)
throw('Drv');
DrvMapBlkSet(dv,first+i);
if (dv->cur_map_blk[(first+i)&(BLK_SIZE/4-1)])
cont=FALSE;
else
i++;
@@ -535,44 +535,44 @@ I64 FAT32AllocContiguousClusters(CPrt *p,I64 cnt)
if (!cont)
first=first+i;
else {
CleanMAPBuf(p);
DrvMapBlkClean(dv);
for (i=0;i<cnt;i++) {
SetFSBuf(p,first+i,0);
DrvMapBlkSet(dv,first+i,0);
if (i+1==cnt)
p->cur_map_blk[(first+i)&(BLK_SIZE/4-1)]=0x0FFFFFFF;
dv->cur_map_blk[(first+i)&(BLK_SIZE/4-1)]=0x0FFFFFFF;
else
p->cur_map_blk[(first+i)&(BLK_SIZE/4-1)]=first+i+1;
LBts(p->buffered_map_dirty_bits,0);
dv->cur_map_blk[(first+i)&(BLK_SIZE/4-1)]=first+i+1;
LBts(&dv->map_blk_dirty,0);
}
CleanMAPBuf(p,0);
DrvMapBlkClean(dv,0);
for (i=0;i<cnt;i++) {
SetFSBuf(p,first+i,1);
DrvMapBlkSet(dv,first+i,1);
if (i+1==cnt)
p->cur_map_blk[(first+i)&(BLK_SIZE/4-1)]=0x0FFFFFFF;
dv->cur_map_blk[(first+i)&(BLK_SIZE/4-1)]=0x0FFFFFFF;
else
p->cur_map_blk[(first+i)&(BLK_SIZE/4-1)]=first+i+1;
LBts(p->buffered_map_dirty_bits,0);
dv->cur_map_blk[(first+i)&(BLK_SIZE/4-1)]=first+i+1;
LBts(&dv->map_blk_dirty,0);
}
CleanMAPBuf(p,1);
DrvMapBlkClean(dv,1);
break;
}
}
} catch {
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
if (unlock_break)
BreakUnlock;
}
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
if (unlock_break)
BreakUnlock;
return first;
}
Bool FAT32DirNew(CPrt *p,U8 *cur_dir,CDirEntry *tempde,Bool free_old_chain)
Bool FAT32DirNew(CDrv *dv,U8 *cur_dir,CDirEntry *tempde,Bool free_old_chain)
{
//See $LK,"::/Doc/CutCorners.TXT"$.
CFAT32DirEntry *buf,*last_buf,*temp_buf,de[3];
@@ -586,12 +586,12 @@ Bool FAT32DirNew(CPrt *p,U8 *cur_dir,CDirEntry *tempde,Bool free_old_chain)
MemSet(&long_name,0,sizeof(CDirEntry));
try {
unlock_break=BreakLock;
unlock=PrtLock(p);
cur_dir_cluster=Name2DirCluster(p,cur_dir);
buf =MAlloc(BLK_SIZE*p->spc);
last_buf=CAlloc(BLK_SIZE*p->spc);
entries_per_cluster=p->spc<<FAT32_ENTRIES_BITS;
RClusters(p,buf,cur_dir_cluster,1);
unlock=DrvLock(dv);
cur_dir_cluster=Name2DirCluster(dv,cur_dir);
buf =MAlloc(BLK_SIZE*dv->spc);
last_buf=CAlloc(BLK_SIZE*dv->spc);
entries_per_cluster=dv->spc<<FAT32_ENTRIES_BITS;
RClusters(dv,buf,cur_dir_cluster,1);
cur_dir_entry=0;
while (ch=*buf[cur_dir_entry].name) {
attr=buf[cur_dir_entry].attr;
@@ -607,8 +607,8 @@ Bool FAT32DirNew(CPrt *p,U8 *cur_dir,CDirEntry *tempde,Bool free_old_chain)
}
if (ch==0xE5 && !written && avail_cnt>=de_cnt) {
MemCpy(&buf[cur_dir_entry],&de,de_cnt*sizeof(CFAT32DirEntry));
WBlks(p,&buf[cur_dir_entry & -FAT32_ENTRIES_PER_BLK],
p->data+cur_dir_cluster*p->spc
WBlks(dv,&buf[cur_dir_entry & -FAT32_ENTRIES_PER_BLK],
dv->data_area+cur_dir_cluster*dv->spc
+cur_dir_entry>>FAT32_ENTRIES_BITS,1);
cur_dir_entry+=de_cnt-1; //gets inc'ed
written=TRUE;
@@ -620,12 +620,12 @@ Bool FAT32DirNew(CPrt *p,U8 *cur_dir,CDirEntry *tempde,Bool free_old_chain)
//Del old entry with same name
if (!StrCmp(long_name.name,tempde->name)) {
if (free_old_chain)
FAT32FreeClusters(p,buf[cur_dir_entry].cluster_lo+
FAT32FreeClusters(dv,buf[cur_dir_entry].cluster_lo+
buf[cur_dir_entry].cluster_hi<<16);
if (!written) {
MemCpy(&buf[cur_dir_entry],&de[de_cnt-1],sizeof(CFAT32DirEntry));
WBlks(p,&buf[cur_dir_entry & -FAT32_ENTRIES_PER_BLK],
p->data+cur_dir_cluster*p->spc
WBlks(dv,&buf[cur_dir_entry & -FAT32_ENTRIES_PER_BLK],
dv->data_area+cur_dir_cluster*dv->spc
+cur_dir_entry>>FAT32_ENTRIES_BITS,1);
written=TRUE;
} else {
@@ -635,8 +635,8 @@ Bool FAT32DirNew(CPrt *p,U8 *cur_dir,CDirEntry *tempde,Bool free_old_chain)
buf[cur_dir_entry-i].attr&RS_ATTR_LONG_NAME_MASK==RS_ATTR_LONG_NAME)
*buf[cur_dir_entry-i++].name=0xE5;
i--;
WBlks(p,&buf[(cur_dir_entry-i)&-FAT32_ENTRIES_PER_BLK],
p->data+cur_dir_cluster*p->spc
WBlks(dv,&buf[(cur_dir_entry-i)&-FAT32_ENTRIES_PER_BLK],
dv->data_area+cur_dir_cluster*dv->spc
+(cur_dir_entry-i)>>FAT32_ENTRIES_BITS,
(i+FAT32_ENTRIES_PER_BLK)>>FAT32_ENTRIES_BITS);
if (i==cur_dir_entry && 0<last_dir_cluster<0x0FFFFFF8) {
@@ -645,8 +645,8 @@ Bool FAT32DirNew(CPrt *p,U8 *cur_dir,CDirEntry *tempde,Bool free_old_chain)
last_buf[entries_per_cluster-i].attr&RS_ATTR_LONG_NAME_MASK==RS_ATTR_LONG_NAME)
*last_buf[entries_per_cluster-i++].name=0xE5;
if (--i>0)
WBlks(p,&buf[(entries_per_cluster-i)&-FAT32_ENTRIES_PER_BLK],
p->data+last_dir_cluster*p->spc
WBlks(dv,&buf[(entries_per_cluster-i)&-FAT32_ENTRIES_PER_BLK],
dv->data_area+last_dir_cluster*dv->spc
+(entries_per_cluster-i)>>FAT32_ENTRIES_BITS,
(i+FAT32_ENTRIES_PER_BLK-1)>>FAT32_ENTRIES_BITS);
}
@@ -659,13 +659,13 @@ Bool FAT32DirNew(CPrt *p,U8 *cur_dir,CDirEntry *tempde,Bool free_old_chain)
if (++cur_dir_entry==entries_per_cluster) {
last_dir_cluster=cur_dir_cluster;
temp_buf=buf; buf=last_buf; last_buf=temp_buf;
c=ClusterNumNext(p,cur_dir_cluster);
c=ClusterNumNext(dv,cur_dir_cluster);
if (!(0<c<0x0FFFFFF8)) {
c=ClustersAlloc(p,cur_dir_cluster,1,FALSE);
MemSet(buf,0,BLK_SIZE*p->spc);
WClusters(p,buf,c,1);
c=ClustersAlloc(dv,cur_dir_cluster,1,FALSE);
MemSet(buf,0,BLK_SIZE*dv->spc);
WClusters(dv,buf,c,1);
} else
RClusters(p,buf,c,1);
RClusters(dv,buf,c,1);
cur_dir_cluster=c;
cur_dir_entry=0;
}
@@ -675,51 +675,51 @@ Bool FAT32DirNew(CPrt *p,U8 *cur_dir,CDirEntry *tempde,Bool free_old_chain)
if (avail_cnt<de_cnt) {
for (i=0;i<avail_cnt;i++)
*buf[cur_dir_entry+i].name=0xE5;
WBlks(p,&buf[cur_dir_entry &-FAT32_ENTRIES_PER_BLK],
p->data+cur_dir_cluster*p->spc
WBlks(dv,&buf[cur_dir_entry &-FAT32_ENTRIES_PER_BLK],
dv->data_area+cur_dir_cluster*dv->spc
+cur_dir_entry>>FAT32_ENTRIES_BITS,1);
cur_dir_entry+=avail_cnt;
if (cur_dir_entry==entries_per_cluster) {
last_dir_cluster=cur_dir_cluster;
temp_buf=buf; buf=last_buf; last_buf=temp_buf;
cur_dir_cluster=ClustersAlloc(p,cur_dir_cluster,1);
cur_dir_cluster=ClustersAlloc(dv,cur_dir_cluster,1);
cur_dir_entry=0;
MemSet(buf,0,BLK_SIZE*p->spc);
WClusters(p,buf,cur_dir_cluster,1);
MemSet(buf,0,BLK_SIZE*dv->spc);
WClusters(dv,buf,cur_dir_cluster,1);
}
}
MemCpy(&buf[cur_dir_entry],&de,de_cnt*sizeof(CFAT32DirEntry));
WBlks(p,&buf[cur_dir_entry &-FAT32_ENTRIES_PER_BLK],
p->data+cur_dir_cluster*p->spc+
WBlks(dv,&buf[cur_dir_entry &-FAT32_ENTRIES_PER_BLK],
dv->data_area+cur_dir_cluster*dv->spc+
cur_dir_entry>>FAT32_ENTRIES_BITS,1);
cur_dir_entry+=de_cnt;
if (cur_dir_entry==entries_per_cluster) {
cur_dir_cluster=ClustersAlloc(p,cur_dir_cluster,1);
MemSet(buf,0,BLK_SIZE*p->spc);
WClusters(p,buf,cur_dir_cluster,1);
cur_dir_cluster=ClustersAlloc(dv,cur_dir_cluster,1);
MemSet(buf,0,BLK_SIZE*dv->spc);
WClusters(dv,buf,cur_dir_cluster,1);
} else {
MemSet(&buf[cur_dir_entry],0,sizeof(CFAT32DirEntry));
WBlks(p,&buf[cur_dir_entry &-FAT32_ENTRIES_PER_BLK],
p->data+cur_dir_cluster*p->spc
WBlks(dv,&buf[cur_dir_entry &-FAT32_ENTRIES_PER_BLK],
dv->data_area+cur_dir_cluster*dv->spc
+cur_dir_entry>>FAT32_ENTRIES_BITS,1);
}
}
Free(last_buf);
Free(buf);
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
if (unlock_break)
BreakUnlock;
} catch {
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
if (unlock_break)
BreakUnlock;
}
return FALSE;
}
I64 FAT32FilesDel(CPrt *p,U8 *cur_dir,U8 *files_find_mask,I64 fuf_flags,
I64 FAT32FilesDel(CDrv *dv,U8 *cur_dir,U8 *files_find_mask,I64 fuf_flags,
Bool del_dir,Bool print_msg)
{
CFAT32DirEntry *buf,*last_buf,*temp_buf;
@@ -731,12 +731,12 @@ I64 FAT32FilesDel(CPrt *p,U8 *cur_dir,U8 *files_find_mask,I64 fuf_flags,
MemSet(&long_name,0,sizeof(CDirEntry));
try {
unlock_break=BreakLock;
PrtLock(p);
cur_dir_cluster=Name2DirCluster(p,cur_dir);
buf =MAlloc(BLK_SIZE*p->spc);
last_buf=CAlloc(BLK_SIZE*p->spc);
entries_per_cluster=p->spc<<FAT32_ENTRIES_BITS;
RClusters(p,buf,cur_dir_cluster,1);
DrvLock(dv);
cur_dir_cluster=Name2DirCluster(dv,cur_dir);
buf =MAlloc(BLK_SIZE*dv->spc);
last_buf=CAlloc(BLK_SIZE*dv->spc);
entries_per_cluster=dv->spc<<FAT32_ENTRIES_BITS;
RClusters(dv,buf,cur_dir_cluster,1);
cur_dir_entry=0;
while (ch=*buf[cur_dir_entry].name) {
attr=buf[cur_dir_entry].attr;
@@ -760,8 +760,8 @@ I64 FAT32FilesDel(CPrt *p,U8 *cur_dir,U8 *files_find_mask,I64 fuf_flags,
buf[cur_dir_entry-i].attr&RS_ATTR_LONG_NAME_MASK==RS_ATTR_LONG_NAME)
*buf[cur_dir_entry-i++].name=0xE5;
i--;
WBlks(p,&buf[(cur_dir_entry-i)&-FAT32_ENTRIES_PER_BLK],
p->data+cur_dir_cluster*p->spc
WBlks(dv,&buf[(cur_dir_entry-i)&-FAT32_ENTRIES_PER_BLK],
dv->data_area+cur_dir_cluster*dv->spc
+(cur_dir_entry-i)>>FAT32_ENTRIES_BITS,
(i+FAT32_ENTRIES_PER_BLK)>>FAT32_ENTRIES_BITS);
if (i==cur_dir_entry && last_dir_cluster!=INVALID_CLUSTER) {
@@ -770,12 +770,12 @@ I64 FAT32FilesDel(CPrt *p,U8 *cur_dir,U8 *files_find_mask,I64 fuf_flags,
last_buf[entries_per_cluster-i].attr&RS_ATTR_LONG_NAME_MASK==RS_ATTR_LONG_NAME)
*last_buf[entries_per_cluster-i++].name=0xE5;
if (--i>0)
WBlks(p,&buf[(entries_per_cluster-i)&-FAT32_ENTRIES_PER_BLK],
p->data+last_dir_cluster*p->spc
WBlks(dv,&buf[(entries_per_cluster-i)&-FAT32_ENTRIES_PER_BLK],
dv->data_area+last_dir_cluster*dv->spc
+(entries_per_cluster-i)>>FAT32_ENTRIES_BITS,
(i+FAT32_ENTRIES_PER_BLK-1)>>FAT32_ENTRIES_BITS);
}
FAT32FreeClusters(p,buf[cur_dir_entry].cluster_lo+
FAT32FreeClusters(dv,buf[cur_dir_entry].cluster_lo+
buf[cur_dir_entry].cluster_hi<<16);
}
}
@@ -785,26 +785,26 @@ I64 FAT32FilesDel(CPrt *p,U8 *cur_dir,U8 *files_find_mask,I64 fuf_flags,
MemSet(&long_name,0,sizeof(CDirEntry));
if (++cur_dir_entry==entries_per_cluster) {
last_dir_cluster=cur_dir_cluster;
cur_dir_cluster=ClusterNumNext(p,cur_dir_cluster,1);
cur_dir_cluster=ClusterNumNext(dv,cur_dir_cluster,1);
temp_buf=buf; buf=last_buf; last_buf=temp_buf;
RClusters(p,buf,cur_dir_cluster,1);
RClusters(dv,buf,cur_dir_cluster,1);
cur_dir_entry=0;
}
}
Free(buf);
Free(last_buf);
PrtUnlock(p);
DrvUnlock(dv);
if (unlock_break)
BreakUnlock;
} catch {
PrtUnlock(p);
DrvUnlock(dv);
if (unlock_break)
BreakUnlock;
}
return result;
}
I64 FAT32FileWrite(CPrt *p,U8 *cur_dir,U8 *name,U8 *buf,I64 size,
I64 FAT32FileWrite(CDrv *dv,U8 *cur_dir,U8 *name,U8 *buf,I64 size,
CDate cdt,I64 attr)
{
CDirEntry de;
@@ -812,34 +812,34 @@ I64 FAT32FileWrite(CPrt *p,U8 *cur_dir,U8 *name,U8 *buf,I64 size,
Bool contiguous;
MemSet(&de,0,sizeof(CDirEntry));
if (size<0) size=0;
if (p->type!=PT_FAT32)
PrintErr("Not FAT32 Partition\n");
if (dv->type!=DVT_FAT32)
PrintErr("Not FAT32 Drv\n");
else if (!CFileNameTo(de.name,name))
PrintErr("Invalid FileName.\n");
else {
FAT32FilesDel(p,cur_dir,de.name,0,FALSE,FALSE);
FAT32FilesDel(dv,cur_dir,de.name,0,FALSE,FALSE);
if (attr & RS_ATTR_CONTIGUOUS)
contiguous=TRUE;
else
contiguous=FALSE;
de.size=size;
if (blk_cnt=(size+BLK_SIZE-1)>>BLK_SIZE_BITS)
c=ClustersAlloc(p,0,(blk_cnt+p->spc-1)/p->spc,contiguous);
c=ClustersAlloc(dv,0,(blk_cnt+dv->spc-1)/dv->spc,contiguous);
else
c=0x0FFFFFFF;
de.cluster=c;
de.attr=attr;
de.datetime=cdt;
if (blk_cnt)
WClustersBlks(p,buf,c,blk_cnt);
FAT32DirNew(p,cur_dir,&de,TRUE);
WClustersBlks(dv,buf,c,blk_cnt);
FAT32DirNew(dv,cur_dir,&de,TRUE);
}
return c;
}
CDirEntry *FAT32FilesFind(U8 *files_find_mask,I64 fuf_flags,CDirEntry *parent=NULL,I64 *_dir_size=NULL)
{
CPrt *p=Fs->cur_prt;
CDrv *dv=Fs->cur_dv;
CFAT32DirEntry *buf;
I64 attr,xsum=0,dir_size=0,sub_dir_size,
cur_dir_cluster,cur_dir_entry,entries_per_cluster;
@@ -849,12 +849,12 @@ CDirEntry *FAT32FilesFind(U8 *files_find_mask,I64 fuf_flags,CDirEntry *parent=NU
throw('FUF');
try {
MemSet(&long_name,0,sizeof(CDirEntry));
PrtLock(p);
cur_dir_cluster=Name2DirCluster(p,Fs->cur_dir);
buf=MAlloc(BLK_SIZE*p->spc);
entries_per_cluster=p->spc<<FAT32_ENTRIES_BITS;
RClusters(Fs->cur_prt,buf,cur_dir_cluster,1);
dir_size+=Fs->cur_prt->spc*BLK_SIZE;
DrvLock(dv);
cur_dir_cluster=Name2DirCluster(dv,Fs->cur_dir);
buf=MAlloc(BLK_SIZE*dv->spc);
entries_per_cluster=dv->spc<<FAT32_ENTRIES_BITS;
RClusters(Fs->cur_dv,buf,cur_dir_cluster,1);
dir_size+=Fs->cur_dv->spc*BLK_SIZE;
cur_dir_entry=0;
while (ch=*buf[cur_dir_entry].name) {
attr=buf[cur_dir_entry].attr;
@@ -874,13 +874,13 @@ CDirEntry *FAT32FilesFind(U8 *files_find_mask,I64 fuf_flags,CDirEntry *parent=NU
tempde->next=result;
result=tempde;
tempde->full_name=DirNameAbs(tempde->name);
PrtUnlock(p);
DrvUnlock(dv);
if (Cd(tempde->name)) {
tempde->sub=FAT32FilesFind(files_find_mask,fuf_flags,tempde,&sub_dir_size);
tempde->size=sub_dir_size;
Cd("..");
}
PrtLock(p);
DrvLock(dv);
} else if ((attr&RS_ATTR_DIR || !Bt(&fuf_flags,FUf_JUST_DIRS)) &&
!(Bt(&fuf_flags,FUf_RECURSE) && *tempde->name=='.' && attr&RS_ATTR_DIR) &&
FilesFindMatch(tempde->name,files_find_mask,fuf_flags)) {
@@ -897,29 +897,29 @@ CDirEntry *FAT32FilesFind(U8 *files_find_mask,I64 fuf_flags,CDirEntry *parent=NU
} else
MemSet(&long_name,0,sizeof(CDirEntry));
if (++cur_dir_entry==entries_per_cluster) {
cur_dir_cluster=ClusterNumNext(p,cur_dir_cluster);
cur_dir_cluster=ClusterNumNext(dv,cur_dir_cluster);
if (cur_dir_cluster==INVALID_CLUSTER)
break;
else {
RClusters(p,buf,cur_dir_cluster,1);
dir_size+=Fs->cur_prt->spc*BLK_SIZE;
RClusters(dv,buf,cur_dir_cluster,1);
dir_size+=Fs->cur_dv->spc*BLK_SIZE;
cur_dir_entry=0;
}
}
}
Free(buf);
PrtUnlock(p);
DrvUnlock(dv);
} catch
PrtUnlock(p);
DrvUnlock(dv);
if (_dir_size)
*_dir_size=dir_size;
return result;
}
Bool FAT32MkDir(CPrt *p,U8 *cur_dir,U8 *name)
Bool FAT32MkDir(CDrv *dv,U8 *cur_dir,U8 *name)
{
I64 size=p->spc<<BLK_SIZE_BITS,c,
cur_dir_cluster=Name2DirCluster(p,cur_dir);
I64 size=dv->spc<<BLK_SIZE_BITS,c,
cur_dir_cluster=Name2DirCluster(dv,cur_dir);
U8 *buf=CAlloc(size);
CDirEntry d_native;
CFAT32DirEntry *dFAT=buf;
@@ -927,7 +927,7 @@ Bool FAT32MkDir(CPrt *p,U8 *cur_dir,U8 *name)
try {
unlock_break=BreakLock;
c=FileWrite(name,buf,size,0,RS_ATTR_DIR,FALSE);
c=FileWrite(name,buf,size,0,RS_ATTR_DIR);
MemSet(&d_native,0,sizeof(CDirEntry));
d_native.attr=RS_ATTR_DIR;
*d_native.name='.';
@@ -947,7 +947,7 @@ Bool FAT32MkDir(CPrt *p,U8 *cur_dir,U8 *name)
d_native.size=0;
d_native.datetime=Now;
FAT32DirFill(dFAT,&d_native);
WClusters(p,buf,c,1);
WClusters(dv,buf,c,1);
Free(buf);
if (unlock_break)
BreakUnlock;
@@ -2,57 +2,57 @@
//ISO2 is ISO13490
//ISO3 is ISO13346
Bool ISOPrtInit(CPrt *p,I64 blk)
Bool ISODrvInit(CDrv *dv,I64 blk)
{
CBlkDev *bdev=p->bdev;
I64 spc=bdev->blk_size>>BLK_SIZE_BITS,i=blk/spc;
CISO1PriDesc *iso=MAlloc(bdev->blk_size);
CBlkDev *bd=dv->bd;
I64 spc=bd->blk_size>>BLK_SIZE_BITS,i=blk/spc;
CISO1PriDesc *iso=MAlloc(bd->blk_size);
CISO1DirEntry *de;
Bool unlock,result=FALSE;
U8 buf[8];
try {
unlock=PrtLock(p);
p->type=PT_ISO9660; //default
p->spc=spc;
p->offset=p->data=p->root_cluster=p->size=0;
unlock=DrvLock(dv);
dv->type=DVT_ISO9660; //default
dv->spc=spc;
dv->base_offset=dv->data_area=dv->root_cluster=dv->size=0;
while (TRUE) {
p->size=MaxI64(p->size,(i+1)*spc);
RBlks(p,iso,i*spc,spc);
dv->size=MaxI64(dv->size,(i+1)*spc);
RBlks(dv,iso,i*spc,spc);
buf[0](U32)=iso->id[0](U32);
buf[4](U16)=iso->id[4](U8);
switch (LstMatch(buf,"CD001\0CDW02\0BEA01\0BOOT2\0NSR02\0NSR03\0TEA01\0",LMF_EXACT)) {
case 0:
p->type=PT_ISO9660;
dv->type=DVT_ISO9660;
switch (iso->type) {
case ISO1T_SUPPLEMENTARY_DESC:
p->data=0;
dv->data_area=0;
de=&iso->root_dir_record;
p->root_cluster=de->loc.little;
p->size=iso->vol_space_size.little*bdev->blk_size>>BLK_SIZE_BITS;
dv->root_cluster=de->loc.little;
dv->size=iso->vol_space_size.little*bd->blk_size>>BLK_SIZE_BITS;
result=TRUE;
goto ipi_done;
case ISO1T_TERMINATOR:
throw('Prt');
throw('Drv');
}
break;
default: //Its normal for ISO13346 to read NULL blk as terminator
PrintErr("File System Not Supported\n");
throw('Prt');
throw('Drv');
}
i++;
}
ipi_done:
Free(iso);
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
} catch {
p->type=PT_ISO9660;
p->spc=spc;
p->offset=p->data=p->root_cluster=0;
dv->type=DVT_ISO9660;
dv->spc=spc;
dv->base_offset=dv->data_area=dv->root_cluster=0;
Free(iso);
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
}
return result;
}
@@ -126,7 +126,7 @@ Bool ISO1CDirFill(CDirEntry *tempde,CISO1DirEntry *de)
return result;
}
Bool ISO1FileFind(CPrt *p,I64 cur_dir_cluster,U8 *name,CDirEntry *_result,I64 fuf_flags=0)
Bool ISO1FileFind(CDrv *dv,I64 cur_dir_cluster,U8 *name,CDirEntry *_result,I64 fuf_flags=0)
{//$LK,"FUF_JUST_DIRS",A="MN:FUF_JUST_DIRS"$, $LK,"FUF_JUST_FILES",A="MN:FUF_JUST_FILES"$
CISO1DirEntry *isoptr,*buf;
U8 dname[CDIR_FILENAME_LEN];
@@ -134,24 +134,24 @@ Bool ISO1FileFind(CPrt *p,I64 cur_dir_cluster,U8 *name,CDirEntry *_result,I64 fu
I64 i;
if (fuf_flags&~FUG_FILE_FIND)
throw('FUF');
PrtChk(p);
if (p->type!=PT_ISO9660)
PrintErr("Not ISO9660 Partition\n");
DrvChk(dv);
if (dv->type!=DVT_ISO9660)
PrintErr("Not ISO9660 Drv\n");
else
try {
unlock=PrtLock(p);
isoptr=MAlloc(p->spc<<BLK_SIZE_BITS);
RClusters(Fs->cur_prt,isoptr,cur_dir_cluster,1);
unlock=DrvLock(dv);
isoptr=MAlloc(dv->spc<<BLK_SIZE_BITS);
RClusters(Fs->cur_dv,isoptr,cur_dir_cluster,1);
if (isoptr->name_len==1 && !isoptr->name) {//curdir
i=(isoptr->size.little+p->spc<<BLK_SIZE_BITS-1)/p->spc<<BLK_SIZE_BITS;
buf=MAlloc(p->spc<<BLK_SIZE_BITS*i);
RClusters(Fs->cur_prt,buf,cur_dir_cluster,i);
i=(isoptr->size.little+dv->spc<<BLK_SIZE_BITS-1)/dv->spc<<BLK_SIZE_BITS;
buf=MAlloc(dv->spc<<BLK_SIZE_BITS*i);
RClusters(Fs->cur_dv,buf,cur_dir_cluster,i);
Free(isoptr);
} else {
buf=isoptr;
i=1;
}
i*=p->spc<<BLK_SIZE_BITS;
i*=dv->spc<<BLK_SIZE_BITS;
isoptr=buf;
while (i>0) {
if (!isoptr->len) {
@@ -163,9 +163,9 @@ Bool ISO1FileFind(CPrt *p,I64 cur_dir_cluster,U8 *name,CDirEntry *_result,I64 fu
if (!StrCmp(name,dname)) {
result=ISO1CDirFill(_result,isoptr);
if (result &&
!(fuf_flags&FUF_JUST_DIRS && !(_result->attr & RS_ATTR_DIR)) &&
!(fuf_flags&FUF_JUST_FILES && _result->attr & RS_ATTR_DIR) )
goto exit_this;
!(fuf_flags&FUF_JUST_DIRS && !(_result->attr & RS_ATTR_DIR)) &&
!(fuf_flags&FUF_JUST_FILES && _result->attr & RS_ATTR_DIR) )
goto iff_done;
else
result=FALSE;
}
@@ -174,51 +174,51 @@ Bool ISO1FileFind(CPrt *p,I64 cur_dir_cluster,U8 *name,CDirEntry *_result,I64 fu
isoptr(U8 *)+=isoptr->len;
}
}
exit_this:
iff_done:
Free(buf);
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
} catch
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
return result;
}
U8 *ISO1FileRead(CPrt *p,U8 *cur_dir,U8 *filename,I64 *_size,I64 *_attr)
U8 *ISO1FileRead(CDrv *dv,U8 *cur_dir,U8 *filename,I64 *_size,I64 *_attr)
{
U8 *buf=NULL;
CDirEntry de;
I64 c,blk_cnt,cur_dir_cluster;
PrtChk(p);
DrvChk(dv);
*_size=0;
*_attr=0;
if (p->type!=PT_ISO9660)
PrintErr("Not ISO9660 Partition\n");
if (dv->type!=DVT_ISO9660)
PrintErr("Not ISO9660 Drv\n");
else
try {
PrtLock(p);
cur_dir_cluster=Name2DirCluster(p,cur_dir);
if (ISO1FileFind(p,cur_dir_cluster,filename,&de,FUF_JUST_FILES)) {
DrvLock(dv);
cur_dir_cluster=Name2DirCluster(dv,cur_dir);
if (ISO1FileFind(dv,cur_dir_cluster,filename,&de,FUF_JUST_FILES)) {
blk_cnt=(de.size+BLK_SIZE-1)>>BLK_SIZE_BITS;
buf=MAlloc(blk_cnt<<BLK_SIZE_BITS+1);
c=de.cluster;
c=RClustersBlks(p,buf,c,blk_cnt);
c=RClustersBlks(dv,buf,c,blk_cnt);
buf[de.size]=0; //Terminate
*_size=de.size;
*_attr=FileAttr(de.name,de.attr);
}
PrtUnlock(p);
DrvUnlock(dv);
} catch
PrtUnlock(p);
DrvUnlock(dv);
return buf;
}
Bool ISO1Cd(U8 *name,I64 cur_dir_cluster)
{
CDirEntry de;
if (Fs->cur_prt->type!=PT_ISO9660)
PrintErr("Not ISO9660 Partition\n");
else if (ISO1FileFind(Fs->cur_prt,cur_dir_cluster,name,&de,FUF_JUST_DIRS))
if (Fs->cur_dv->type!=DVT_ISO9660)
PrintErr("Not ISO9660 Drv\n");
else if (ISO1FileFind(Fs->cur_dv,cur_dir_cluster,name,&de,FUF_JUST_DIRS))
return TRUE;
else {
"%s ",name;
@@ -229,25 +229,25 @@ Bool ISO1Cd(U8 *name,I64 cur_dir_cluster)
CDirEntry *ISO1FilesFind(U8 *files_find_mask,I64 fuf_flags,CDirEntry *parent=NULL)
{
CPrt *p=Fs->cur_prt;
CDrv *dv=Fs->cur_dv;
CISO1DirEntry *buf,*buf2,*isoptr;
I64 i,cur_dir_cluster=Name2DirCluster(p,Fs->cur_dir);
I64 i,cur_dir_cluster=Name2DirCluster(dv,Fs->cur_dir);
CDirEntry *result=NULL,*tempde;
if (fuf_flags&~FUG_FILES_FIND)
throw('FUF');
isoptr=MAlloc(p->spc<<BLK_SIZE_BITS);
RClusters(Fs->cur_prt,isoptr,cur_dir_cluster,1);
isoptr=MAlloc(dv->spc<<BLK_SIZE_BITS);
RClusters(Fs->cur_dv,isoptr,cur_dir_cluster,1);
if (isoptr->name_len==1 && !isoptr->name) {//curdir
i=(isoptr->size.little+p->spc<<BLK_SIZE_BITS-1)/p->spc<<BLK_SIZE_BITS;
buf=MAlloc(p->spc<<BLK_SIZE_BITS*i);
RClusters(Fs->cur_prt,buf,cur_dir_cluster,i);
i=(isoptr->size.little+dv->spc<<BLK_SIZE_BITS-1)/dv->spc<<BLK_SIZE_BITS;
buf=MAlloc(dv->spc<<BLK_SIZE_BITS*i);
RClusters(Fs->cur_dv,buf,cur_dir_cluster,i);
Free(isoptr);
} else {
buf=isoptr;
i=1;
}
buf2=buf;
i*=p->spc<<BLK_SIZE_BITS;
i*=dv->spc<<BLK_SIZE_BITS;
while (i>0) {
if (!buf->len) {
buf(U8 *)++;
+175 -174
View File
@@ -1,41 +1,41 @@
// See $LK,"RedSea File System",A="FI:::/Doc/RedSea.TXT"$
U0 RedSeaFSFreeFreeLst(CPrt *p)
U0 RedSeaFreeFreeLst(CDrv *dv)
{
CFreeLst *tempf,*tempf1;
Bool unlock;
try {
unlock=PrtLock(p);
if (tempf=p->next_free) {
while (tempf!=&p->next_free) {
unlock=DrvLock(dv);
if (tempf=dv->next_free) {
while (tempf!=&dv->next_free) {
tempf1=tempf->next;
Free(tempf);
tempf=tempf1;
}
}
p->next_free=NULL;
dv->next_free=NULL;
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
} catch
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
}
U0 RedSeaFSFreeLstBuild(CPrt *p)
U0 RedSeaFreeLstBuild(CDrv *dv)
{
Bool unlock;
CFreeLst *tempf;
I64 i,first=0,max_cluster=p->size+p->offset-p->data;
I64 i,first=dv->data_area,max_blk=dv->size+dv->base_offset;
try {
unlock=PrtLock(p);
if (p->next_free)
RedSeaFSFreeFreeLst(p);
QueInit(&p->next_free);
while (first<max_cluster) {
unlock=DrvLock(dv);
if (dv->next_free)
RedSeaFreeFreeLst(dv);
QueInit(&dv->next_free);
while (first<max_blk) {
i=0; //count free clusters
while (first+i<max_cluster) {
SetFSBuf(p,first+i);
if (Bt(p->cur_map_blk,(first+i)&(BLK_SIZE<<3-1)))
while (first+i<max_blk) {
DrvMapBlkSet(dv,first+i);
if (Bt(dv->cur_map_blk,(first+i-dv->data_area)&(BLK_SIZE<<3-1)))
break;
else
i++;
@@ -44,72 +44,73 @@ U0 RedSeaFSFreeLstBuild(CPrt *p)
tempf=AMAlloc(sizeof(CFreeLst));
tempf->size=i;
tempf->start=first;
QueIns(tempf,p->last_free);
QueIns(tempf,dv->last_free);
}
first+=i+1;
}
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
} catch
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
}
U0 RedSeaFSPrtInit(CPrt *p)
U0 RedSeaDrvInit(CDrv *dv)
{
CBootStruct br;
CRedSeaBoot br;
Bool unlock;
try {
unlock=PrtLock(p);
RBlks(p,&br,p->offset,1);
unlock=DrvLock(dv);
RBlks(dv,&br,dv->base_offset,1);
if (br.signature!=MBR_PT_REDSEA || br.signature2!=0xAA55)
throw('Prt');
p->type=PT_REDSEA;
RedSeaFSFreeFreeLst(p);
p->spc=1;
p->size=br.sects;
p->data=p->offset+br.bitmap_sects;
p->root_cluster=br.root_cluster;
p->map1=p->map2=p->offset+1;
MapBufAlloc(p,1);
throw('Drv');
dv->type=DVT_REDSEA;
RedSeaFreeFreeLst(dv);
dv->spc=1;
dv->size=br.sects;
dv->data_area=dv->base_offset+br.bitmap_sects;
dv->root_cluster=br.root_cluster;
dv->map1=dv->map2=dv->base_offset+1;
DrvMapBlkAlloc(dv);
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
} catch
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
}
Bool RedSeaFSDrvValidate(U8 drv_let)
Bool RedSeaDrvValidate(U8 drv_let)
{
CPrt *p;
CBootStruct br;
CDrv *dv;
CRedSeaBoot br;
Bool result=FALSE;
try {
p=Drv2Prt(drv_let);
if (p->type==PT_REDSEA && RBlks(p,&br,p->offset,1) &&
dv=Let2Drv(drv_let);
if (dv->type==DVT_REDSEA && RBlks(dv,&br,dv->base_offset,1) &&
br.signature==MBR_PT_REDSEA && br.signature2==0xAA55 &&
br.sects==p->size)
br.sects==dv->size)
result=TRUE;
} catch
Fs->catch_except=TRUE;
return result;
}
U0 RedSeaFSFmt(U8 drv_let,Bool quick=TRUE)
U0 RedSeaFmt(U8 drv_let,Bool quick=TRUE)
{
U8 *root_dir;
CDirEntry *d_native;
CBootStruct *br=CAlloc(BLK_SIZE);
CPrt *p=Drv2Prt(drv_let);
CRedSeaBoot *br=CAlloc(BLK_SIZE);
CDrv *dv=Let2Drv(drv_let);
I64 i,n;
try {
PrtLock(p);
// SetDrvType(drv_let,PT_REDSEA);
SetDrvType(drv_let,PT_FAT32);
p->type=PT_REDSEA;
DrvLock(dv);
// DrvTypeSet(drv_let,DVT_REDSEA);
DrvTypeSet(drv_let,DVT_FAT32);
dv->type=DVT_REDSEA;
br->signature=MBR_PT_REDSEA;
br->signature2=0xAA55;
br->sects=p->size;
br->base_offset=dv->base_offset; //For CD/DVD image copy.
br->sects=dv->size;
n=(br->sects+BLK_SIZE<<3-1)/BLK_SIZE<<3;
br->bitmap_sects=n;
br->unique_id=GetTSC^Now()(U64);
@@ -118,14 +119,14 @@ U0 RedSeaFSFmt(U8 drv_let,Bool quick=TRUE)
if (quick)
i=n+1;
else
i=p->size;
WZeroBlks(p,p->offset,i);
i=dv->size;
WZeroBlks(dv,dv->base_offset,i);
WBlks(p,br,p->offset,1);
RedSeaFSPrtInit(p);
ClustersAlloc(p,0,1,FALSE); //Alloc #1
br->root_cluster=ClustersAlloc(p,0,1,FALSE);
WBlks(p,br,p->offset,1);
WBlks(dv,br,dv->base_offset,1);
RedSeaDrvInit(dv);
ClustersAlloc(dv,0,1,FALSE); //Alloc #1
br->root_cluster=ClustersAlloc(dv,0,1,FALSE);
WBlks(dv,br,dv->base_offset,1);
root_dir=CAlloc(BLK_SIZE);
d_native=root_dir-offset(CDirEntry.start);
@@ -144,16 +145,16 @@ U0 RedSeaFSFmt(U8 drv_let,Bool quick=TRUE)
d_native->cluster=br->root_cluster;
d_native->datetime=Now;
WBlks(p,root_dir,p->data+br->root_cluster,1);
RedSeaFSPrtInit(p);
PrtUnlock(p);
WBlks(dv,root_dir,br->root_cluster,1);
RedSeaDrvInit(dv);
DrvUnlock(dv);
} catch
PrtUnlock(p);
DrvUnlock(dv);
Free(br);
Free(root_dir);
}
Bool RedSeaFSFileFind(CPrt *p,I64 cur_dir_cluster,U8 *name,CDirEntry *_result,I64 fuf_flags=0)
Bool RedSeaFileFind(CDrv *dv,I64 cur_dir_cluster,U8 *name,CDirEntry *_result,I64 fuf_flags=0)
{//$LK,"FUF_JUST_DIRS",A="MN:FUF_JUST_DIRS"$, $LK,"FUF_JUST_FILES",A="MN:FUF_JUST_FILES"$
CDirEntry *buf,*buf2,*ptr;
U8 dname[CDIR_FILENAME_LEN];
@@ -162,22 +163,22 @@ Bool RedSeaFSFileFind(CPrt *p,I64 cur_dir_cluster,U8 *name,CDirEntry *_result,I6
if (fuf_flags&~FUG_FILE_FIND)
throw('FUF');
MemSet(_result,0,sizeof(CDirEntry));
PrtChk(p);
if (p->type!=PT_REDSEA)
PrintErr("Not RedSea Partition\n");
DrvChk(dv);
if (dv->type!=DVT_REDSEA)
PrintErr("Not RedSea Drv\n");
else if (!CFileNameTo(dname,name))
PrintErr("Invalid FileName.\n");
else
try {
unlock=PrtLock(p);
unlock=DrvLock(dv);
buf2=MAlloc(BLK_SIZE);
RClusters(p,buf2,cur_dir_cluster,1);
RBlks(dv,buf2,cur_dir_cluster,1);
ptr=buf2(U8 *)-offset(CDirEntry.start);
buf=MAlloc(ptr->size);
RClustersBlks(p,buf,cur_dir_cluster,ptr->size>>BLK_SIZE_BITS);
RBlks(dv,buf,cur_dir_cluster,ptr->size>>BLK_SIZE_BITS);
Free(buf2);
ptr=buf(U8 *)-offset(CDirEntry.start);
*ptr->name='.';
ptr->name[1]=0;
@@ -185,60 +186,60 @@ Bool RedSeaFSFileFind(CPrt *p,I64 cur_dir_cluster,U8 *name,CDirEntry *_result,I6
if (!(ch=*ptr->name))
break;
else if (!(ptr->attr & RS_ATTR_DELETED) &&
!(fuf_flags&FUF_JUST_DIRS && !(ptr->attr & RS_ATTR_DIR)) &&
!(fuf_flags&FUF_JUST_FILES && ptr->attr & RS_ATTR_DIR) &&
!StrCmp(dname,ptr->name)) {
!(fuf_flags&FUF_JUST_DIRS && !(ptr->attr & RS_ATTR_DIR)) &&
!(fuf_flags&FUF_JUST_FILES && ptr->attr & RS_ATTR_DIR) &&
!StrCmp(dname,ptr->name)) {
MemCpy(&_result->attr,&ptr->attr,CDIR_SIZE);
result=TRUE;
goto exit_this;
goto rsff_done;
}
ptr(U8 *)+=CDIR_SIZE;
}
exit_this:
rsff_done:
Free(buf);
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
} catch
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
return result;
}
U8 *RedSeaFSFileRead(CPrt *p,U8 *cur_dir,U8 *filename,I64 *_size,I64 *_attr)
U8 *RedSeaFileRead(CDrv *dv,U8 *cur_dir,U8 *filename,I64 *_size,I64 *_attr)
{
U8 *buf=NULL;
CDirEntry de;
I64 c,blk_cnt,cur_dir_cluster;
PrtChk(p);
DrvChk(dv);
*_size=0;
*_attr=0;
if (p->type!=PT_REDSEA)
PrintErr("Not RedSea Partition\n");
if (dv->type!=DVT_REDSEA)
PrintErr("Not RedSea Drv\n");
else
try {
PrtLock(p);
cur_dir_cluster=Name2DirCluster(p,cur_dir);
if (RedSeaFSFileFind(p,cur_dir_cluster,filename,&de,FUF_JUST_FILES)) {
DrvLock(dv);
cur_dir_cluster=Name2DirCluster(dv,cur_dir);
if (RedSeaFileFind(dv,cur_dir_cluster,filename,&de,FUF_JUST_FILES)) {
blk_cnt=(de.size+BLK_SIZE-1)>>BLK_SIZE_BITS;
buf=MAlloc(blk_cnt<<BLK_SIZE_BITS+1);
c=de.cluster;
c=RClustersBlks(p,buf,c,blk_cnt);
c=RBlks(dv,buf,c,blk_cnt);
buf[de.size]=0; //Terminate
*_size=de.size;
*_attr=FileAttr(de.name,de.attr);
}
PrtUnlock(p);
DrvUnlock(dv);
} catch
PrtUnlock(p);
DrvUnlock(dv);
return buf;
}
Bool RedSeaFSCd(U8 *name,I64 cur_dir_cluster)
Bool RedSeaCd(U8 *name,I64 cur_dir_cluster)
{
CDirEntry de;
if (Fs->cur_prt->type!=PT_REDSEA)
PrintErr("Not RedSea Partition\n");
else if (RedSeaFSFileFind(Fs->cur_prt,cur_dir_cluster,name,&de,FUF_JUST_DIRS))
if (Fs->cur_dv->type!=DVT_REDSEA)
PrintErr("Not RedSea Drv\n");
else if (RedSeaFileFind(Fs->cur_dv,cur_dir_cluster,name,&de,FUF_JUST_DIRS))
return TRUE;
else {
"%s ",name;
@@ -247,22 +248,22 @@ Bool RedSeaFSCd(U8 *name,I64 cur_dir_cluster)
return FALSE;
}
U0 RedSeaFSFreeClusters(CPrt *p,I64 c,I64 cnt)
U0 RedSeaFreeClusters(CDrv *dv,I64 c,I64 cnt)
{
CFreeLst *tempf;
Bool found=FALSE,unlock,unlock_break;
PrtChk(p);
DrvChk(dv);
if (!c) return;
if (p->type!=PT_REDSEA)
PrintErr("Not RedSea Partition\n");
if (dv->type!=DVT_REDSEA)
PrintErr("Not RedSea Drv\n");
else
try {
unlock_break=BreakLock;
unlock=PrtLock(p);
if (!p->next_free)
RedSeaFSFreeLstBuild(p);
tempf=p->next_free;
while (!found && tempf!=&p->next_free) {
unlock=DrvLock(dv);
if (!dv->next_free)
RedSeaFreeLstBuild(dv);
tempf=dv->next_free;
while (!found && tempf!=&dv->next_free) {
if (tempf->start+tempf->size==c) {
tempf->size+=cnt;
found=TRUE;
@@ -277,42 +278,42 @@ U0 RedSeaFSFreeClusters(CPrt *p,I64 c,I64 cnt)
tempf=AMAlloc(sizeof(CFreeLst));
tempf->size=cnt;
tempf->start=c;
QueIns(tempf,p->last_free);
QueIns(tempf,dv->last_free);
}
while (cnt-->0) {
SetFSBuf(p,c);
LBtr(p->cur_map_blk,c&(BLK_SIZE<<3-1));
LBts(p->buffered_map_dirty_bits,0);
DrvMapBlkSet(dv,c);
LBtr(dv->cur_map_blk,(c-dv->data_area)&(BLK_SIZE<<3-1));
LBts(&dv->map_blk_dirty,0);
c++;
}
CleanMAPBuf(p);
DrvMapBlkClean(dv);
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
if (unlock_break)
BreakUnlock;
} catch {
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
if (unlock_break)
BreakUnlock;
}
}
I64 RedSeaFSAllocClusters(CPrt *p,I64 cnt)
I64 RedSeaAllocClusters(CDrv *dv,I64 cnt)
{
CFreeLst *tempf,*best_free=NULL;
I64 i,first,best_size=MAX_I64;
Bool unlock,unlock_break;
if (cnt<=0)
Dbg;
throw('Drv');
try {
unlock_break=BreakLock;
unlock=PrtLock(p);
if (!p->next_free)
RedSeaFSFreeLstBuild(p);
tempf=p->next_free;
while (tempf!=&p->next_free) {
unlock=DrvLock(dv);
if (!dv->next_free)
RedSeaFreeLstBuild(dv);
tempf=dv->next_free;
while (tempf!=&dv->next_free) {
if (tempf->size>=cnt && tempf->size<best_size) {
best_free=tempf;
best_size=tempf->size;
@@ -322,14 +323,14 @@ I64 RedSeaFSAllocClusters(CPrt *p,I64 cnt)
tempf=tempf->next;
}
if (!best_free)
Dbg;
throw('Drv');
first=best_free->start;
for (i=0;i<cnt;i++) {
SetFSBuf(p,first+i);
LBts(p->cur_map_blk,(first+i)&(BLK_SIZE<<3-1));
LBts(p->buffered_map_dirty_bits,0);
DrvMapBlkSet(dv,first+i);
LBts(dv->cur_map_blk,(first+i-dv->data_area)&(BLK_SIZE<<3-1));
LBts(&dv->map_blk_dirty,0);
}
CleanMAPBuf(p);
DrvMapBlkClean(dv);
if (best_free->size-=cnt)
best_free->start+=cnt;
else {
@@ -337,36 +338,36 @@ I64 RedSeaFSAllocClusters(CPrt *p,I64 cnt)
Free(best_free);
}
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
if (unlock_break)
BreakUnlock;
} catch {
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
if (unlock_break)
BreakUnlock;
}
return first;
}
Bool RedSeaFSDirNew(CPrt *p,U8 *cur_dir,CDirEntry *de,Bool free_old_chain)
Bool RedSeaDirNew(CDrv *dv,U8 *cur_dir,CDirEntry *de,Bool free_old_chain)
{
CDirEntry *buf,*buf2,*ptr,de2;
CBootStruct *br;
CRedSeaBoot *br;
I64 c,ch,i=1,j=0,n=BLK_SIZE/CDIR_SIZE,dir_size,cur_dir_cluster;
Bool written=FALSE,unlock,unlock_break;
U8 *temp,*parent_dir;
try {
unlock_break=BreakLock;
de->attr|=RS_ATTR_CONTIGUOUS;
unlock=PrtLock(p);
cur_dir_cluster=Name2DirCluster(p,cur_dir);
unlock=DrvLock(dv);
cur_dir_cluster=Name2DirCluster(dv,cur_dir);
buf2=MAlloc(BLK_SIZE);
RClusters(p,buf2,cur_dir_cluster,1);
RBlks(dv,buf2,cur_dir_cluster,1);
ptr=buf2(U8 *)-offset(CDirEntry.start);
buf=MAlloc(ptr->size);
RClustersBlks(p,buf,cur_dir_cluster,ptr->size>>BLK_SIZE_BITS);
RBlks(dv,buf,cur_dir_cluster,ptr->size>>BLK_SIZE_BITS);
dir_size=ptr->size;
ptr=buf(U8 *)-offset(CDirEntry.start)+CDIR_SIZE;
@@ -376,26 +377,26 @@ Bool RedSeaFSDirNew(CPrt *p,U8 *cur_dir,CDirEntry *de,Bool free_old_chain)
if (!written)
MemCpy(&ptr->start,&de->start,CDIR_SIZE);
if ((i+1)*CDIR_SIZE+j<<BLK_SIZE_BITS<dir_size)
WBlks(p,buf(U8 *)+j<<BLK_SIZE_BITS,p->data+cur_dir_cluster+j,1);
WBlks(dv,buf(U8 *)+j<<BLK_SIZE_BITS,cur_dir_cluster+j,1);
else {
buf2=CAlloc(dir_size+BLK_SIZE);
MemCpy(buf2,buf,dir_size);
RedSeaFSFreeClusters(p,cur_dir_cluster,dir_size>>BLK_SIZE_BITS);
RedSeaFreeClusters(dv,cur_dir_cluster,dir_size>>BLK_SIZE_BITS);
dir_size+=BLK_SIZE;
c=ClustersAlloc(p,0,dir_size>>BLK_SIZE_BITS,TRUE);
c=ClustersAlloc(dv,0,dir_size>>BLK_SIZE_BITS,TRUE);
Free(buf);
buf=buf2;
ptr=buf(U8 *)-offset(CDirEntry.start);
ptr->size=dir_size;
ptr->cluster=c;
WClustersBlks(p,buf,c,dir_size>>BLK_SIZE_BITS);
if (cur_dir_cluster==p->root_cluster) {
WBlks(dv,buf,c,dir_size>>BLK_SIZE_BITS);
if (cur_dir_cluster==dv->root_cluster) {
br=CAlloc(BLK_SIZE);
RBlks(p,br,p->offset,1);
RBlks(dv,br,dv->base_offset,1);
br->root_cluster=c;
WBlks(p,br,p->offset,1);
WBlks(dv,br,dv->base_offset,1);
Free(br);
p->root_cluster=c;
dv->root_cluster=c;
} else {
temp=StrNew(cur_dir);
parent_dir=StrNew(cur_dir);
@@ -404,13 +405,13 @@ Bool RedSeaFSDirNew(CPrt *p,U8 *cur_dir,CDirEntry *de,Bool free_old_chain)
Free(parent_dir);
parent_dir=StrNew("/");
}
if (RedSeaFSFileFind(p,Name2DirCluster(p,parent_dir),
if (RedSeaFileFind(dv,Name2DirCluster(dv,parent_dir),
temp,&de2,FUF_JUST_DIRS)) {
de2.cluster=c;
de2.size=dir_size;
RedSeaFSDirNew(p,parent_dir,&de2,FALSE);
RedSeaDirNew(dv,parent_dir,&de2,FALSE);
} else
Dbg;
throw('Drv');
Free(temp);
Free(parent_dir);
}
@@ -419,19 +420,19 @@ Bool RedSeaFSDirNew(CPrt *p,U8 *cur_dir,CDirEntry *de,Bool free_old_chain)
} else if (ptr->attr & RS_ATTR_DELETED) {
if (!written) {
MemCpy(&ptr->start,&de->start,CDIR_SIZE);
WBlks(p,buf(U8 *)+j<<BLK_SIZE_BITS,p->data+cur_dir_cluster+j,1);
WBlks(dv,buf(U8 *)+j<<BLK_SIZE_BITS,cur_dir_cluster+j,1);
written=TRUE;
}
} else {
if (!StrCmp(de->name,ptr->name)) {
if (free_old_chain)
RedSeaFSFreeClusters(p,ptr->cluster,
RedSeaFreeClusters(dv,ptr->cluster,
(ptr->size+BLK_SIZE-1)>>BLK_SIZE_BITS);
if (!written)
MemCpy(&ptr->start,&de->start,CDIR_SIZE);
else
ptr->attr|=RS_ATTR_DELETED;
WBlks(p,buf(U8 *)+j<<BLK_SIZE_BITS,p->data+cur_dir_cluster+j,1);
WBlks(dv,buf(U8 *)+j<<BLK_SIZE_BITS,cur_dir_cluster+j,1);
break;
}
}
@@ -443,19 +444,19 @@ Bool RedSeaFSDirNew(CPrt *p,U8 *cur_dir,CDirEntry *de,Bool free_old_chain)
}
Free(buf);
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
if (unlock_break)
BreakUnlock;
} catch {
if (unlock)
PrtUnlock(p);
DrvUnlock(dv);
if (unlock_break)
BreakUnlock;
}
return FALSE;
}
I64 RedSeaFSFilesDel(CPrt *p,U8 *cur_dir,U8 *files_find_mask,I64 fuf_flags,
I64 RedSeaFilesDel(CDrv *dv,U8 *cur_dir,U8 *files_find_mask,I64 fuf_flags,
Bool del_dir,Bool print_msg)
{
CDirEntry *buf,*buf2,*ptr;
@@ -463,14 +464,14 @@ I64 RedSeaFSFilesDel(CPrt *p,U8 *cur_dir,U8 *files_find_mask,I64 fuf_flags,
Bool unlock_break;
try {
unlock_break=BreakLock;
PrtLock(p);
cur_dir_cluster=Name2DirCluster(p,cur_dir);
DrvLock(dv);
cur_dir_cluster=Name2DirCluster(dv,cur_dir);
buf2=MAlloc(BLK_SIZE);
RClusters(p,buf2,cur_dir_cluster,1);
RBlks(dv,buf2,cur_dir_cluster,1);
ptr=buf2(U8 *)-offset(CDirEntry.start);
buf=MAlloc(ptr->size);
RClustersBlks(p,buf,cur_dir_cluster,ptr->size>>BLK_SIZE_BITS);
RBlks(dv,buf,cur_dir_cluster,ptr->size>>BLK_SIZE_BITS);
Free(buf2);
ptr=buf(U8 *)-offset(CDirEntry.start);
@@ -486,8 +487,8 @@ I64 RedSeaFSFilesDel(CPrt *p,U8 *cur_dir,U8 *files_find_mask,I64 fuf_flags,
if (print_msg)
"Del %s\n",ptr->name;
ptr->attr|=RS_ATTR_DELETED;
WBlks(p,buf(U8 *)+j<<BLK_SIZE_BITS,p->data+cur_dir_cluster+j,1);
RedSeaFSFreeClusters(p,ptr->cluster,(ptr->size+BLK_SIZE-1)>>BLK_SIZE_BITS);
WBlks(dv,buf(U8 *)+j<<BLK_SIZE_BITS,cur_dir_cluster+j,1);
RedSeaFreeClusters(dv,ptr->cluster,(ptr->size+BLK_SIZE-1)>>BLK_SIZE_BITS);
}
ptr(U8 *)+=CDIR_SIZE;
if (++i>=n) {
@@ -496,68 +497,68 @@ I64 RedSeaFSFilesDel(CPrt *p,U8 *cur_dir,U8 *files_find_mask,I64 fuf_flags,
}
}
Free(buf);
PrtUnlock(p);
DrvUnlock(dv);
if (unlock_break)
BreakUnlock;
} catch {
PrtUnlock(p);
DrvUnlock(dv);
if (unlock_break)
BreakUnlock;
}
return result;
}
I64 RedSeaFSFileWrite(CPrt *p,U8 *cur_dir,U8 *name,U8 *buf,I64 size,
I64 RedSeaFileWrite(CDrv *dv,U8 *cur_dir,U8 *name,U8 *buf,I64 size,
CDate cdt,I64 attr)
{
CDirEntry de;
I64 c=0,blk_cnt;
MemSet(&de,0,sizeof(CDirEntry));
if (size<0) size=0;
if (p->type!=PT_REDSEA)
PrintErr("Not RedSea Partition\n");
if (dv->type!=DVT_REDSEA)
PrintErr("Not RedSea Drv\n");
else if (!CFileNameTo(de.name,name))
PrintErr("Invalid FileName.\n");
else {
RedSeaFSFilesDel(p,cur_dir,de.name,0,FALSE,FALSE);
RedSeaFilesDel(dv,cur_dir,de.name,0,FALSE,FALSE);
de.size=size;
if (blk_cnt=(size+BLK_SIZE-1)>>BLK_SIZE_BITS)
c=ClustersAlloc(p,0,blk_cnt,TRUE); //Always contiguous
c=ClustersAlloc(dv,0,blk_cnt,TRUE); //Always contiguous
else
c=INVALID_CLUSTER;
de.cluster=c;
de.attr=attr|RS_ATTR_CONTIGUOUS;
de.datetime=cdt;
if (blk_cnt)
WClustersBlks(p,buf,c,blk_cnt);
RedSeaFSDirNew(p,cur_dir,&de,TRUE);
WBlks(dv,buf,c,blk_cnt);
RedSeaDirNew(dv,cur_dir,&de,TRUE);
}
return c;
}
CDirEntry *RedSeaFSFilesFind(U8 *files_find_mask,I64 fuf_flags,CDirEntry *parent=NULL)
CDirEntry *RedSeaFilesFind(U8 *files_find_mask,I64 fuf_flags,CDirEntry *parent=NULL)
{
CPrt *p=Fs->cur_prt;
CDrv *dv=Fs->cur_dv;
CDirEntry *buf,*buf2,*ptr,*result=NULL,*tempde;
I64 ch,cur_dir_cluster;
if (fuf_flags&~FUG_FILES_FIND)
throw('FUF');
try {
PrtLock(p);
cur_dir_cluster=Name2DirCluster(p,Fs->cur_dir);
DrvLock(dv);
cur_dir_cluster=Name2DirCluster(dv,Fs->cur_dir);
buf2=MAlloc(BLK_SIZE);
RClusters(p,buf2,cur_dir_cluster,1);
RBlks(dv,buf2,cur_dir_cluster,1);
ptr=buf2(U8 *)-offset(CDirEntry.start);
buf=MAlloc(ptr->size);
RClustersBlks(p,buf,cur_dir_cluster,ptr->size>>BLK_SIZE_BITS);
RBlks(dv,buf,cur_dir_cluster,ptr->size>>BLK_SIZE_BITS);
Free(buf2);
ptr=buf(U8 *)-offset(CDirEntry.start);
*ptr->name='.';
ptr->name[1]=0;
ptr(U8 *)+=CDIR_SIZE;
ptr->cluster=Name2ParentDirCluster(p,Fs->cur_dir);
ptr->cluster=Name2ParentDirCluster(dv,Fs->cur_dir);
ptr(U8 *)-=CDIR_SIZE;
while (TRUE) {
if (!(ch=*ptr->name))
@@ -570,12 +571,12 @@ CDirEntry *RedSeaFSFilesFind(U8 *files_find_mask,I64 fuf_flags,CDirEntry *parent
tempde->next=result;
result=tempde;
tempde->full_name=DirNameAbs(tempde->name);
PrtUnlock(p);
DrvUnlock(dv);
if (Cd(tempde->name)) {
tempde->sub=RedSeaFSFilesFind(files_find_mask,fuf_flags,tempde);
tempde->sub=RedSeaFilesFind(files_find_mask,fuf_flags,tempde);
Cd("..");
}
PrtLock(p);
DrvLock(dv);
} else if ((tempde->attr&RS_ATTR_DIR || !Bt(&fuf_flags,FUf_JUST_DIRS)) &&
!(Bt(&fuf_flags,FUf_RECURSE) && *tempde->name=='.' && tempde->attr&RS_ATTR_DIR) &&
FilesFindMatch(tempde->name,files_find_mask,fuf_flags)) {
@@ -588,22 +589,22 @@ CDirEntry *RedSeaFSFilesFind(U8 *files_find_mask,I64 fuf_flags,CDirEntry *parent
ptr(U8 *)+=CDIR_SIZE;
}
Free(buf);
PrtUnlock(p);
DrvUnlock(dv);
} catch
PrtUnlock(p);
DrvUnlock(dv);
return result;
}
Bool RedSeaFSMkDir(CPrt *p,U8 *cur_dir,U8 *name)
Bool RedSeaMkDir(CDrv *dv,U8 *cur_dir,U8 *name)
{
I64 size=BLK_SIZE,c,cur_dir_cluster=Name2DirCluster(p,cur_dir);
I64 size=BLK_SIZE,c,cur_dir_cluster=Name2DirCluster(dv,cur_dir);
U8 *buf=CAlloc(size);
CDirEntry *d_native=buf-offset(CDirEntry.start);
Bool unlock_break;
try {
unlock_break=BreakLock;
c=FileWrite(name,buf,size,0,RS_ATTR_DIR,FALSE);
c=FileWrite(name,buf,size,0,RS_ATTR_DIR);
d_native->attr=RS_ATTR_DIR|RS_ATTR_CONTIGUOUS;
StrCpy(d_native->name,name);
d_native->cluster=c;
@@ -618,7 +619,7 @@ Bool RedSeaFSMkDir(CPrt *p,U8 *cur_dir,U8 *name)
d_native->cluster=cur_dir_cluster;
d_native->size=0;
d_native->datetime=Now;
WClusters(p,buf,c,1);
WBlks(dv,buf,c,1);
Free(buf);
if (unlock_break)
BreakUnlock;