LTCD_070816.ISO
This commit is contained in:
1 parent
d14bbc24f9
commit
0e9364ff4c
506 files changed
+157705
-41812
No files matched your search
@@ -0,0 +1,554 @@
|
||||
void LockPartition(LTPartition *p)
|
||||
{
|
||||
BoolU4 old_preempt=Preempt(OFF);
|
||||
LTBlkDev *bdev=p->bdev;
|
||||
CheckLTPartition(p);
|
||||
if (p->owning_task!=Fs) {
|
||||
while (Bts(&p->flags,MPEf_LOCKED))
|
||||
SwapInNext;
|
||||
if (bdev->type==LTBDT_FDC)
|
||||
FDCGet(bdev);
|
||||
p->owning_task=Fs;
|
||||
}
|
||||
Preempt(old_preempt);
|
||||
}
|
||||
|
||||
BoolU8 UnlockPartition(LTPartition *p,BoolU4 reset=FALSE)
|
||||
{
|
||||
LTBlkDev *bdev=p->bdev;
|
||||
BoolU4 old_preempt=Preempt(OFF),result=FALSE;
|
||||
CheckLTPartition(p);
|
||||
if (p->owning_task==Fs) {
|
||||
if (reset) {
|
||||
bdev->flags&=~(LTBDF_INITIALIZED|LTBDF_INIT_IN_PROGRESS);
|
||||
if (bdev->irq)
|
||||
LBtr(&sema_irq_busy[bdev->irq],0);
|
||||
}
|
||||
p->owning_task=0;
|
||||
if (bdev->type==LTBDT_FDC)
|
||||
FDCFree(bdev);
|
||||
Btr(&p->flags,MPEf_LOCKED);
|
||||
result=TRUE;
|
||||
SwapInNext; //Prevent deadlock
|
||||
}
|
||||
Preempt(old_preempt);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void AllocMAPBuf(LTPartition *p,U8 num_blks)
|
||||
{
|
||||
CheckLTPartition(p);
|
||||
AFree(p->cur_MAP_blk);
|
||||
AFree(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=AMAllocZ((num_blks+7)>>3);
|
||||
p->cur_MAP_blk_num=0;
|
||||
RBlks(p,p->cur_MAP_blk,p->MAP1,p->num_buffered_MAP_blks,FALSE);
|
||||
}
|
||||
|
||||
|
||||
void CleanMAPBuf(LTPartition *p,I8 MAP_select=-1)
|
||||
{
|
||||
U8 i;
|
||||
if (MAP_select==-1 || MAP_select==0) {
|
||||
for (i=0;i<p->num_buffered_MAP_blks;i++)
|
||||
if (Bt(p->buffered_MAP_dirty_bits,i))
|
||||
WBlks(p,p->cur_MAP_blk+i<<BLK_SIZE_BITS,p->MAP1+i+p->cur_MAP_blk_num,1,FALSE);
|
||||
}
|
||||
if (MAP_select==-1 || MAP_select==1) {
|
||||
for (i=0;i<p->num_buffered_MAP_blks;i++)
|
||||
if (Btr(p->buffered_MAP_dirty_bits,i))
|
||||
WBlks(p,p->cur_MAP_blk+i<<BLK_SIZE_BITS,p->MAP2+i+p->cur_MAP_blk_num,1,FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void SetLTBuf(LTPartition *p,U8 c)
|
||||
{
|
||||
U8 MAP_blk_num=c>>(BLK_SIZE_BITS+3);
|
||||
if (MAP_blk_num!=p->cur_MAP_blk_num) {
|
||||
CleanMAPBuf(p);
|
||||
p->cur_MAP_blk_num=MAP_blk_num;
|
||||
RBlks(p,p->cur_MAP_blk,p->MAP1+p->cur_MAP_blk_num,1,FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
#define ZERO_BUF_SIZE 2048
|
||||
void WZeroBlks(LTPartition *p,U8 blk,U8 cnt,BoolU4 unlock)
|
||||
{
|
||||
U8 n;
|
||||
U1 *z=MAllocZ(ZERO_BUF_SIZE<<BLK_SIZE_BITS);
|
||||
while (cnt) {
|
||||
n=cnt;
|
||||
if (n>ZERO_BUF_SIZE)
|
||||
n=ZERO_BUF_SIZE;
|
||||
WBlks(p,z,blk,n,unlock);
|
||||
blk+=n;
|
||||
cnt-=n;
|
||||
SwapInNext; //Prevent locking
|
||||
}
|
||||
Free(z);
|
||||
}
|
||||
|
||||
//Very dangerous
|
||||
BoolU8 SetDriveType(I1 drive,U8 type=PT_LT)
|
||||
{
|
||||
I8 i,j,ext_base,num_partition;
|
||||
U8 offset,cur_type;
|
||||
MasterBootStruct mbr;
|
||||
LTBlkDev *bd=DriveToBlkDev(drive);
|
||||
num_partition=bd->partition_base-'A';
|
||||
switch (bd->type) {
|
||||
case LTBDT_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==0xF)
|
||||
j=i;
|
||||
else {
|
||||
if ((num_partition+'A')==drive) {
|
||||
mbr.p[i].type=type;
|
||||
mbr.p[i].active=0x80;
|
||||
ATAWriteBlks(bd,&mbr,offset,1);
|
||||
return TRUE;
|
||||
}
|
||||
num_partition++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (j<0)
|
||||
break;
|
||||
if (mbr.p[j].offset==0)
|
||||
break;
|
||||
if (ext_base==INVALID_CLUSTER) {
|
||||
offset=mbr.p[j].offset;
|
||||
ext_base=offset;
|
||||
} else
|
||||
offset=mbr.p[j].offset+ext_base;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BoolU8 InitBlkDev(LTBlkDev *bd,BoolU4 unlock)
|
||||
{
|
||||
LTPartition *p=DriveToPartition(bd->partition_base),*p2;
|
||||
LTBlkDev *bd2;
|
||||
BoolU4 old_preempt=Preempt(OFF),result=FALSE;
|
||||
if (!(bd->flags & LTBDF_INITIALIZED)) {
|
||||
bd->flags|=LTBDF_INITIALIZED |
|
||||
LTBDF_INIT_IN_PROGRESS;
|
||||
switch(bd->type) {
|
||||
case LTBDT_RAM:
|
||||
bd->RAM_disk=AMAllocZ((bd->max_blk+1)<<BLK_SIZE_BITS);
|
||||
bd->max_blk=MSize(bd->RAM_disk)>>BLK_SIZE_BITS-1;
|
||||
p->type=PT_LT;
|
||||
//TODO: finish unlock?
|
||||
FormatLT(bd->partition_base,FALSE);
|
||||
break;
|
||||
case LTBDT_FDC:
|
||||
if (!monitor_floppy_tss) {
|
||||
monitor_floppy_tss=Spawn(&MonitorFDCTsk,"FLOPPY MANAGER");
|
||||
monitor_floppy_tss->user_data0=bd;
|
||||
}
|
||||
bd->max_reads=1;
|
||||
bd->max_writes=1;
|
||||
bd->read_freq=750;
|
||||
bd->write_freq=150;
|
||||
break;
|
||||
case LTBDT_ATA:
|
||||
bd->max_reads=128;
|
||||
bd->max_writes=1;
|
||||
bd->read_freq=2000;
|
||||
bd->write_freq=500;
|
||||
IDEInit(bd,TRUE);
|
||||
break;
|
||||
case LTBDT_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>ltdc_size*BLK_SIZE/4)
|
||||
bd->max_reads=(ltdc_size/BLK_SIZE/4) & ~3;
|
||||
if (bd->max_reads<128)
|
||||
bd->max_reads=128;
|
||||
bd->max_writes=0xFFFF*4;
|
||||
bd->read_freq=1000;
|
||||
bd->write_freq=250;
|
||||
IDEInit(bd,TRUE);
|
||||
p->size=bd->max_blk+1;
|
||||
break;
|
||||
case LTBDT_LT_FILE:
|
||||
if (bd->flags & LTBDF_FORMAT) {
|
||||
//TODO: finish unlock?
|
||||
bd->f=FOpen(bd->filename,"wc",p->size);
|
||||
if (!bd->f)
|
||||
throw(EXCEPT_PARTITION,1);
|
||||
//TODO: finish unlock?
|
||||
FormatLT(bd->partition_base,TRUE);
|
||||
} else {
|
||||
bd->f=FOpen(bd->filename,"wc+");
|
||||
if (!bd->f)
|
||||
throw(EXCEPT_PARTITION,2);
|
||||
bd->max_blk=(FSize(bd->f)+BLK_SIZE-1)>>BLK_SIZE_BITS-1;
|
||||
p->size=bd->max_blk+1;
|
||||
InitLTPartition(p,unlock);
|
||||
}
|
||||
break;
|
||||
case LTBDT_NON_LT_FILE:
|
||||
bd->max_reads=128;
|
||||
bd->max_writes=128;
|
||||
bd->read_freq=2000;
|
||||
bd->write_freq=500;
|
||||
if (bd->flags & LTBDF_FORMAT)
|
||||
FormatLT(bd->partition_base,TRUE);
|
||||
else {
|
||||
p2=DriveToPartition(bd->non_lt_drive);
|
||||
bd2=p2->bdev;
|
||||
bd->min_blk=p->offset;
|
||||
bd->max_blk=p2->offset+p2->size-1; //temp
|
||||
p->size=p2->size-(p->offset-p2->offset); //temp
|
||||
InitLTPartition(p,unlock);
|
||||
bd->max_blk=p->offset+p->size-1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (bd->flags & LTBDF_READ_CACHE)
|
||||
InvalidateDiskCache(p,unlock);
|
||||
bd->flags=bd->flags & ~LTBDF_INIT_IN_PROGRESS;
|
||||
result=TRUE;
|
||||
}
|
||||
Preempt(old_preempt);
|
||||
return result;
|
||||
}
|
||||
|
||||
BoolU8 RBlks(LTPartition *p,U1 *buf, U8 blk, U8 cnt,BoolU4 unlock)
|
||||
{
|
||||
BoolU4 result=TRUE;
|
||||
LTBlkDev *bdev=p->bdev;
|
||||
CheckLTPartition(p);
|
||||
try {
|
||||
LockPartition(p);
|
||||
InitBlkDev(bdev,FALSE);
|
||||
if ((p->offset && blk<p->offset) || blk+cnt>p->offset+p->size)
|
||||
throw(EXCEPT_PARTITION,3);
|
||||
blk+=bdev->offset;
|
||||
|
||||
if (bdev->flags & LTBDF_READ_CACHE)
|
||||
RCache(p,&buf,&blk,&cnt);
|
||||
if (cnt) {
|
||||
if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SOUND],0))
|
||||
Sound(bdev->read_freq);
|
||||
result=p->RBlks(p,buf,blk,cnt);
|
||||
bdev->last_jiffy=Jiffies;
|
||||
if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SOUND],0))
|
||||
Sound(0);
|
||||
if (bdev->flags & LTBDF_READ_CACHE)
|
||||
LTDCAdd(p,buf,blk,cnt);
|
||||
if (bdev->type!=LTBDT_RAM)
|
||||
disk_reads+=cnt;
|
||||
}
|
||||
if (unlock)
|
||||
UnlockPartition(p);
|
||||
} catch
|
||||
if (unlock)
|
||||
UnlockPartition(p);
|
||||
return result;
|
||||
}
|
||||
|
||||
BoolU8 WBlks(LTPartition *p,U1 *buf, U8 blk, U8 cnt,BoolU4 unlock)
|
||||
{
|
||||
BoolU4 result;
|
||||
LTBlkDev *bdev=p->bdev;
|
||||
CheckLTPartition(p);
|
||||
try {
|
||||
LockPartition(p);
|
||||
InitBlkDev(bdev,FALSE);
|
||||
if ((bdev->flags & LTBDF_READ_ONLY) &&
|
||||
!(bdev->flags & LTBDF_READ_ONLY_OVERRIDE))
|
||||
throw(EXCEPT_BLKDEV,0);
|
||||
if ((p->offset && blk<p->offset) || blk+cnt>p->offset+p->size)
|
||||
throw(EXCEPT_PARTITION,4);
|
||||
blk+=bdev->offset;
|
||||
if (cnt) {
|
||||
if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SOUND],0))
|
||||
Sound(bdev->write_freq);
|
||||
result=p->WBlks(p,buf,blk,cnt);
|
||||
bdev->last_jiffy=Jiffies;
|
||||
if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SOUND],0))
|
||||
Sound(0);
|
||||
if (bdev->flags & LTBDF_READ_CACHE)
|
||||
LTDCAdd(p,buf,blk,cnt);
|
||||
if (bdev->type!=LTBDT_RAM)
|
||||
disk_writes+=cnt;
|
||||
}
|
||||
if (unlock)
|
||||
UnlockPartition(p);
|
||||
} catch
|
||||
if (unlock)
|
||||
UnlockPartition(p);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void InvalidateDiskCache(LTPartition *p,BoolU4 unlock)
|
||||
{
|
||||
LTBlkDev *bdev=p->bdev;
|
||||
CheckLTPartition(p);
|
||||
try {
|
||||
LockPartition(p);
|
||||
InitBlkDev(bdev,FALSE);
|
||||
if (bdev->flags & LTBDF_READ_CACHE)
|
||||
LTDCInvalidate(p);
|
||||
if (bdev->type==LTBDT_FDC)
|
||||
InitLTPartition(p,FALSE);
|
||||
else if (p->type==PT_ISO9660) {
|
||||
if (!(bdev->flags & LTBDF_READ_ONLY_OVERRIDE))
|
||||
InitISOPartition(p,FALSE);
|
||||
}
|
||||
if (unlock)
|
||||
UnlockPartition(p);
|
||||
} catch
|
||||
if (unlock)
|
||||
UnlockPartition(p);
|
||||
}
|
||||
|
||||
void ChangeDisk(I1 drive_letter=0)
|
||||
{
|
||||
LTBlkDev *bdev=DriveToBlkDev(drive_letter);
|
||||
if (!InitBlkDev(bdev,TRUE) && bdev->flags & LTBDF_REMOVABLE)
|
||||
InvalidateDiskCache(DriveToPartition(drive_letter),TRUE);
|
||||
Drive(drive_letter); //TODO: might preempt off
|
||||
FreeLTFreeList(DriveToPartition(drive_letter),TRUE);
|
||||
}
|
||||
|
||||
|
||||
void PartitionRep()
|
||||
{
|
||||
I8 i;
|
||||
I1 ch;
|
||||
U2 u2;
|
||||
U1 u1;
|
||||
LTPartition *p;
|
||||
LTBlkDev *bdev;
|
||||
coutln "\r\nDefined Partitions:\r\n";
|
||||
for (i=0;i<32;i++) {
|
||||
p=&local_partitions[i];
|
||||
bdev=p->bdev;
|
||||
if (p->type) {
|
||||
cout "$$FG,PURPLE$$";
|
||||
if (p==default_partition)
|
||||
cout "*";
|
||||
else
|
||||
cout " ";
|
||||
ch=PartitionToDrive(p);
|
||||
cout ch," ";
|
||||
if (p->type==PT_LT)
|
||||
cout "LT ";
|
||||
else if (p->type==PT_FAT12)
|
||||
cout "FAT12 ";
|
||||
else if (p->type==PT_FAT32)
|
||||
cout "FAT32 ";
|
||||
else if (p->type==PT_ISO9660)
|
||||
cout "ISO9660";
|
||||
else
|
||||
cout "-------";
|
||||
cout " ",SysTextSub(bdev->type,"ST_BLKDEV_TYPES")," ";
|
||||
u2=bdev->base0; cout u2," ";
|
||||
u1=bdev->irq; cout u1," ";
|
||||
u1=bdev->unit; coutln u1,"$$FG$$";
|
||||
coutln p->offset,"-",p->offset+p->size-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ReleaseTaskPartitions()
|
||||
{
|
||||
I8 i;
|
||||
LTPartition *p;
|
||||
for (i=0;i<32;i++) {
|
||||
p=&local_partitions[i];
|
||||
if (p->owning_task==Fs) {
|
||||
UnlockPartition(p,TRUE);
|
||||
if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SOUND],0))
|
||||
Sound(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U8 NextClusterNum(LTPartition *p,U8 c,U8 cnt,BoolU4 unlock)
|
||||
{
|
||||
CheckLTPartition(p);
|
||||
if (!cnt || !c) return c;
|
||||
try {
|
||||
LockPartition(p);
|
||||
if (p->type==PT_ISO9660 || p->type==PT_LT)
|
||||
c+=cnt;
|
||||
else
|
||||
c=INVALID_CLUSTER;
|
||||
if (unlock)
|
||||
UnlockPartition(p);
|
||||
} catch
|
||||
if (unlock)
|
||||
UnlockPartition(p);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
U8 ClusterBlk(LTPartition *p,U8 c)
|
||||
{
|
||||
CheckLTPartition(p);
|
||||
return p->data+c*p->spc;
|
||||
}
|
||||
|
||||
U8 RClusters(LTPartition *p,U1 *buf,U8 c,U8 cnt,BoolU4 unlock,BoolU4 update_display=FALSE)
|
||||
{
|
||||
nounusedwarn update_display;
|
||||
CheckLTPartition(p);
|
||||
if (!cnt) return c;
|
||||
try {
|
||||
LockPartition(p);
|
||||
if (p->type==PT_ISO9660 || p->type==PT_LT) {
|
||||
RBlks(p,buf,p->data+c*p->spc,p->spc*cnt,FALSE);
|
||||
c+=cnt;
|
||||
} else {
|
||||
while (cnt && c && c!=INVALID_CLUSTER) {
|
||||
RBlks(p,buf,p->data+c*p->spc,p->spc,FALSE);
|
||||
buf+=p->spc<<BLK_SIZE_BITS;
|
||||
c=NextClusterNum(p,c,1,FALSE);
|
||||
cnt--;
|
||||
}
|
||||
if (cnt)
|
||||
Debugger;
|
||||
}
|
||||
if (unlock)
|
||||
UnlockPartition(p);
|
||||
} catch
|
||||
if (unlock)
|
||||
UnlockPartition(p);
|
||||
return c;
|
||||
}
|
||||
|
||||
BoolU8 ToLTFilename(I1 *dst,I1 *src)
|
||||
{
|
||||
MemSet(dst,0,LT_MAX_FILENAME_LEN+1);
|
||||
if (!CheckFileName(src))
|
||||
return FALSE;
|
||||
StrCpy(dst,src);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
U8 NameToDirCluster(LTPartition *p,I1 *name,BoolU4 unlock)
|
||||
{
|
||||
BoolU4 cont=TRUE;
|
||||
U8 cur_dir_cluster;
|
||||
LTDirEntry de;
|
||||
I1 *buf=NewStr(name),*buf2=NewStr(name);
|
||||
CheckLTPartition(p);
|
||||
try {
|
||||
LockPartition(p);
|
||||
cur_dir_cluster=p->root_cluster;
|
||||
while (*buf && cont) {
|
||||
RemoveFirstSeg(buf,"/",buf2);
|
||||
if (*buf2) {
|
||||
if (p->type==PT_LT)
|
||||
cont=FindLTFile(p,cur_dir_cluster,
|
||||
buf2,&de,TRUE,FALSE,FALSE);
|
||||
else if (p->type==PT_ISO9660)
|
||||
cont=FindISOFile(p,cur_dir_cluster,
|
||||
buf2,&de,TRUE,FALSE,FALSE);
|
||||
else cont=FALSE;
|
||||
cur_dir_cluster=de.cluster;
|
||||
}
|
||||
}
|
||||
if (!cont) {
|
||||
cout name," ";
|
||||
PutSysTextErr("ST_FILE_NOT_FOUND");
|
||||
cur_dir_cluster=0;
|
||||
}
|
||||
if (unlock)
|
||||
UnlockPartition(p);
|
||||
} catch
|
||||
if (unlock)
|
||||
UnlockPartition(p);
|
||||
Free(buf);
|
||||
Free(buf2);
|
||||
return cur_dir_cluster;
|
||||
}
|
||||
|
||||
U8 NameToParentDirCluster(LTPartition *p,I1 *name,BoolU4 unlock)
|
||||
{
|
||||
BoolU4 cont=TRUE;
|
||||
U8 cur_dir_cluster,cur_dir_cluster2;
|
||||
LTDirEntry de;
|
||||
I1 *buf=NewStr(name),*buf2=NewStr(name);
|
||||
CheckLTPartition(p);
|
||||
try {
|
||||
LockPartition(p);
|
||||
cur_dir_cluster=p->root_cluster;
|
||||
cur_dir_cluster2=p->root_cluster;
|
||||
while (*buf && cont) {
|
||||
cur_dir_cluster2=cur_dir_cluster;
|
||||
RemoveFirstSeg(buf,"/",buf2);
|
||||
if (*buf2) {
|
||||
if (p->type==PT_LT)
|
||||
cont=FindLTFile(p,cur_dir_cluster,
|
||||
buf2,&de,TRUE,FALSE,FALSE);
|
||||
else if (p->type==PT_ISO9660)
|
||||
cont=FindISOFile(p,cur_dir_cluster,
|
||||
buf2,&de,TRUE,FALSE,FALSE);
|
||||
else cont=FALSE;
|
||||
cur_dir_cluster=de.cluster;
|
||||
}
|
||||
}
|
||||
if (!cont) {
|
||||
cout name," ";
|
||||
PutSysTextErr("ST_FILE_NOT_FOUND");
|
||||
cur_dir_cluster2=0;
|
||||
}
|
||||
if (unlock)
|
||||
UnlockPartition(p);
|
||||
} catch
|
||||
if (unlock)
|
||||
UnlockPartition(p);
|
||||
Free(buf);
|
||||
Free(buf2);
|
||||
return cur_dir_cluster2;
|
||||
}
|
||||
|
||||
|
||||
U8 WClusters(LTPartition *p,U1 *buf,U8 c,U8 cnt,BoolU4 unlock,BoolU4 update_display=FALSE)
|
||||
{
|
||||
nounusedwarn update_display;
|
||||
CheckLTPartition(p);
|
||||
try {
|
||||
LockPartition(p);
|
||||
if (p->type==PT_LT) {
|
||||
WBlks(p,buf,p->data+c*p->spc,p->spc*cnt,FALSE);
|
||||
c=0;
|
||||
}
|
||||
if (unlock)
|
||||
UnlockPartition(p);
|
||||
} catch
|
||||
if (unlock)
|
||||
UnlockPartition(p);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
//c=0 means first cluster in chain
|
||||
U8 AllocClusters(LTPartition *p,U8 c,U8 cnt,BoolU4 contiguous,BoolU4 unlock)
|
||||
{
|
||||
nounusedwarn contiguous;
|
||||
if (!cnt)
|
||||
return c;
|
||||
CheckLTPartition(p);
|
||||
if (p->type==PT_LT)
|
||||
return AllocLTClusters(p,cnt,unlock);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,400 @@
|
||||
void MapDrive(I1 ch,LTPartition *p)
|
||||
{
|
||||
drive_to_partition[ToUpper(ch)-'A']=p;
|
||||
p->drive=ToUpper(ch);
|
||||
}
|
||||
|
||||
BoolU8 Drive(I1 drive_letter)
|
||||
{
|
||||
LTPartition *p;
|
||||
LTBlkDev *bdev;
|
||||
BoolU4 different=FALSE;
|
||||
LTPartition *new_partition=DriveToPartition(drive_letter);
|
||||
if (!new_partition) {
|
||||
PutSysTextErr("ST_INVALID_DRIVE");
|
||||
return FALSE;
|
||||
}
|
||||
if (new_partition!=Fs->cur_partition) {
|
||||
different=TRUE;
|
||||
Fs->cur_partition=new_partition;
|
||||
}
|
||||
p=Fs->cur_partition;
|
||||
CheckLTPartition(p);
|
||||
bdev=p->bdev;
|
||||
CheckLTBlkDev(bdev);
|
||||
if (different) {
|
||||
if ((bdev->flags & LTBDF_REMOVABLE) &&
|
||||
!(bdev->flags & LTBDF_INITIALIZED) )
|
||||
ChangeDisk(p->drive);
|
||||
if (bdev->type==LTBDT_RAM ||
|
||||
bdev->type==LTBDT_NON_LT_FILE ||
|
||||
bdev->type==LTBDT_LT_FILE)
|
||||
InitBlkDev(bdev,TRUE);
|
||||
}
|
||||
Free(Fs->cur_dir);
|
||||
Fs->cur_dir=NewStr("/");
|
||||
if (p->type==PT_ISO9660 || p->type==PT_LT)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BoolU8 Cd(I1 *name,BoolU4 make_dirs=FALSE)
|
||||
{
|
||||
I8 maxlen;
|
||||
BoolU4 result=TRUE;
|
||||
I1 *change_to_buf,*new_cur_dir,*buf,*hdir;
|
||||
LTPartition *p;
|
||||
U8 cur_dir_cluster=0;
|
||||
if (!*name) return TRUE;
|
||||
if (name[1]==':') {
|
||||
if (*name==':') {
|
||||
if (Fs->cur_partition!=default_partition)
|
||||
if (!Drive(*name)) return FALSE;
|
||||
} else {
|
||||
if (Fs->cur_partition!=
|
||||
DriveToPartition(*name))
|
||||
if (!Drive(*name)) return FALSE;
|
||||
}
|
||||
name+=2;
|
||||
}
|
||||
if (*name=='/' || !*name) {
|
||||
Free(Fs->cur_dir);
|
||||
Fs->cur_dir=NewStr("/");
|
||||
if (*name)
|
||||
name++;
|
||||
}
|
||||
change_to_buf=MStrUtil(name,
|
||||
SU_REMOVE_LEADING|SU_REMOVE_TRAILING|
|
||||
SU_DISCARD_PARITY|SU_REMOVE_CTRL_CHARS);
|
||||
maxlen=StrLen(Fs->cur_dir)+1+StrLen(change_to_buf)+1;
|
||||
new_cur_dir=MAlloc(maxlen);
|
||||
buf=MAlloc(maxlen);
|
||||
StrCpy(new_cur_dir,Fs->cur_dir);
|
||||
while (*change_to_buf && result) {
|
||||
RemoveFirstSeg(change_to_buf,"/",buf);
|
||||
if (!*buf)
|
||||
StrCpy(new_cur_dir,"/");
|
||||
else if (!StrCmp(buf,"..")) {
|
||||
RemoveLastSeg(new_cur_dir,"/");
|
||||
if (!*new_cur_dir)
|
||||
StrCpy(new_cur_dir,"/");
|
||||
} else if (!StrCmp(buf,".")) {
|
||||
;
|
||||
} else if (*buf) {
|
||||
if (!StrCmp(buf,"HOME")) {
|
||||
hdir=HomeDirStr;
|
||||
result=Cd(hdir);
|
||||
Free(new_cur_dir);
|
||||
new_cur_dir=MAlloc(maxlen+StrLen(hdir));
|
||||
StrCpy(new_cur_dir,hdir+2);
|
||||
Free(hdir);
|
||||
} else {
|
||||
p=Fs->cur_partition;
|
||||
cur_dir_cluster=NameToDirCluster(p,new_cur_dir,TRUE);
|
||||
if (p->type==PT_LT)
|
||||
result=CdLT(buf,cur_dir_cluster);
|
||||
else if (p->type==PT_ISO9660)
|
||||
result=CdISO(buf,cur_dir_cluster);
|
||||
else result=FALSE;
|
||||
if (!result && make_dirs) {
|
||||
Free(Fs->cur_dir);
|
||||
Fs->cur_dir=NewStr(new_cur_dir);
|
||||
result=MkDir(buf);
|
||||
}
|
||||
if (result) {
|
||||
if (StrCmp(new_cur_dir,"/"))
|
||||
StrCat(new_cur_dir,"/");
|
||||
StrCat(new_cur_dir,buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Free(Fs->cur_dir);
|
||||
Fs->cur_dir=NewStr(new_cur_dir);
|
||||
Free(buf);
|
||||
Free(change_to_buf);
|
||||
Free(new_cur_dir);
|
||||
return result;
|
||||
}
|
||||
|
||||
void DelLTFileAccess(LTFileAccess *fa)
|
||||
{
|
||||
LTBlkDev *bdev;
|
||||
if (!fa) return;
|
||||
bdev=fa->old_partition->bdev;
|
||||
if (!(bdev->flags & LTBDF_INIT_IN_PROGRESS)) {
|
||||
if (fa->old_dir) {
|
||||
Drive(PartitionToDrive(fa->old_partition));
|
||||
Cd(fa->old_dir);
|
||||
}
|
||||
} else {
|
||||
Fs->cur_partition=fa->old_partition;
|
||||
Free(Fs->cur_dir);
|
||||
Fs->cur_dir=NewStr("/");
|
||||
}
|
||||
Free(fa->old_dir);
|
||||
Free(fa->mask);
|
||||
Free(fa);
|
||||
}
|
||||
|
||||
LTFileAccess *NewLTFileAccess(I1 *mask,BoolU4 make_mask=FALSE,BoolU4 make_dirs=FALSE)
|
||||
{
|
||||
BoolU4 valid=TRUE;
|
||||
I1 *buf,*my_mask,*temp_mask;
|
||||
BoolU4 old_silent;
|
||||
LTFileAccess *fa=MAllocZ(sizeof(LTFileAccess));
|
||||
my_mask=MStrUtil(mask,
|
||||
SU_REMOVE_LEADING|SU_REMOVE_TRAILING|
|
||||
SU_DISCARD_PARITY|SU_REMOVE_CTRL_CHARS);
|
||||
temp_mask=my_mask;
|
||||
fa->old_dir=NewStr(Fs->cur_dir);
|
||||
fa->old_partition=Fs->cur_partition;
|
||||
if (*my_mask && my_mask[1]==':') {
|
||||
if (Fs->cur_partition!=DriveToPartition(*my_mask))
|
||||
if (!Drive(*my_mask)) valid=FALSE;
|
||||
my_mask+=2;
|
||||
}
|
||||
if (StrStr(my_mask,"HOME")) { //TODO
|
||||
if (Fs->cur_partition!=DriveToPartition(':'))
|
||||
Drive(':');
|
||||
}
|
||||
fa->p=Fs->cur_partition;
|
||||
CheckLTPartition(fa->p);
|
||||
buf=MAlloc(StrLen(my_mask)+2);
|
||||
StrCpy(buf,my_mask);
|
||||
fa->mask=MAlloc(StrLen(my_mask)+2);
|
||||
RemoveLastSeg(buf,"/",fa->mask);
|
||||
if (*my_mask=='/' && !*buf)
|
||||
StrCpy(buf,"/");
|
||||
if (*buf)
|
||||
if (!Cd(buf,make_dirs))
|
||||
valid=FALSE;
|
||||
if (valid && make_mask) {
|
||||
if (!*fa->mask) {
|
||||
Free(fa->mask);
|
||||
fa->mask=NewStr("*");
|
||||
} else {
|
||||
if (!make_dirs || CheckFileName(fa->mask)) {
|
||||
old_silent=Silent(ON);
|
||||
if (Cd(fa->mask,make_dirs)) {
|
||||
Free(fa->mask);
|
||||
fa->mask=NewStr("*");
|
||||
}
|
||||
Silent(old_silent);
|
||||
}
|
||||
}
|
||||
}
|
||||
Free(buf);
|
||||
Free(temp_mask);
|
||||
if (!valid) {
|
||||
DelLTFileAccess(fa);
|
||||
fa=NULL;
|
||||
// throw(EXCEPT_FILE);
|
||||
}
|
||||
return fa;
|
||||
}
|
||||
|
||||
LTDirEntry *FindFiles(I1 *wild,U8 fuf_flags=0)
|
||||
{
|
||||
LTDirEntry *result=NULL;
|
||||
LTFileAccess *fa=NewLTFileAccess(wild,TRUE);
|
||||
if (fa) {
|
||||
result=SysFindFiles(fa->mask,fuf_flags);
|
||||
DelLTFileAccess(fa);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
BoolU8 IsDir(I1 *dir_name)
|
||||
{
|
||||
BoolU4 result=FALSE;
|
||||
I1 *mask=MSPrintF("%s/*",dir_name);
|
||||
BoolU4 old_silent=Silent(ON);
|
||||
LTFileAccess *fa=NewLTFileAccess(mask);
|
||||
if (fa) {
|
||||
result=TRUE;
|
||||
DelLTFileAccess(fa);
|
||||
}
|
||||
Free(mask);
|
||||
Silent(old_silent);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Dir(I1 *wild=NULL,BoolU4 full=FALSE)
|
||||
{
|
||||
I1 *w;
|
||||
LTFileAccess *fa;
|
||||
if (!wild)
|
||||
w=NewStr("*"); //We must do this because of bug that prevents str defaults
|
||||
else
|
||||
w=NewStr(wild);
|
||||
fa=NewLTFileAccess(w,TRUE);
|
||||
if (fa) {
|
||||
DirLT(fa->mask,full);
|
||||
DelLTFileAccess(fa);
|
||||
}
|
||||
Free(w);
|
||||
}
|
||||
|
||||
|
||||
void Del(I1 *wild,BoolU4 print_msg=TRUE)
|
||||
{
|
||||
LTFileAccess *fa=NewLTFileAccess(wild);
|
||||
if (fa) {
|
||||
if (fa->p->type==PT_LT)
|
||||
DelLTFiles(fa->p,Fs->cur_dir,fa->mask,FALSE,print_msg);
|
||||
DelLTFileAccess(fa);
|
||||
}
|
||||
}
|
||||
|
||||
U1 *ReadFile(I1 *filename,U8 *size=NULL,U8 *attr=NULL,BoolU4 raw=FALSE)
|
||||
{
|
||||
SysHashEntry *temph;
|
||||
I1 *absname;
|
||||
U1 *result=NULL;
|
||||
U8 size2=0,attr2=0;
|
||||
LTFileAccess *fa;
|
||||
ArcCompressStruct *ac=NULL;
|
||||
|
||||
if (attr)
|
||||
*attr=0;
|
||||
absname=AbsoluteFileName(filename);
|
||||
if (!raw && (temph=FindHashEntry(absname,adam_tss->hash_table,HTT_FILE))) {
|
||||
if (FileAttr(absname) & LT_ATTR_COMPRESSED) {
|
||||
ac=temph->user_data0;
|
||||
if (size)
|
||||
*size=ac->expanded_size;
|
||||
if (attr)
|
||||
*attr=FileAttr(absname,*attr);
|
||||
result=ExpandBuf(ac);
|
||||
} else { //Not implimented
|
||||
result=MAlloc(temph->user_data1+1);
|
||||
MemCpy(result,temph->user_data0,temph->user_data1);
|
||||
result[temph->user_data1]=0; //Terminate
|
||||
if (size)
|
||||
*size=temph->user_data1;
|
||||
}
|
||||
} else {
|
||||
fa=NewLTFileAccess(absname);
|
||||
if (fa) {
|
||||
if (fa->p->type==PT_LT)
|
||||
result=ReadLTFile(fa->p,Fs->cur_dir,fa->mask,&size2,&attr2,raw,&ac);
|
||||
else if (fa->p->type==PT_ISO9660)
|
||||
result=ReadISOFile(fa->p,Fs->cur_dir,fa->mask,&size2,&attr2,raw,&ac);
|
||||
while (!result && StrCmp(Fs->cur_dir,"/")) {
|
||||
Cd("..");
|
||||
if (Fs->cur_partition->type==PT_LT)
|
||||
result=ReadLTFile(fa->p,Fs->cur_dir,fa->mask,&size2,&attr2,raw,&ac);
|
||||
else if (fa->p->type==PT_ISO9660)
|
||||
result=ReadISOFile(fa->p,Fs->cur_dir,fa->mask,&size2,&attr2,raw,&ac);
|
||||
}
|
||||
if (!result) {
|
||||
cout filename," ";
|
||||
PutSysTextErr("ST_FILE_NOT_FOUND");
|
||||
}
|
||||
DelLTFileAccess(fa);
|
||||
}
|
||||
if (size)
|
||||
*size=size2;
|
||||
if (attr)
|
||||
*attr=attr2;
|
||||
if (!raw && attr2 & LT_ATTR_RESIDENT) {
|
||||
temph=AMAllocZ(sizeof(SysHashEntry));
|
||||
temph->str=ANewStr(absname);
|
||||
temph->type=HTT_FILE;
|
||||
temph->use_cnt=0;
|
||||
temph->source_link=NULL;
|
||||
temph->user_data0=AMAllocIdentical(ac);
|
||||
temph->user_data1=size2;
|
||||
AddSysHashEntry(temph,adam_tss->hash_table);
|
||||
}
|
||||
Free(ac);
|
||||
}
|
||||
Free(absname);
|
||||
return result;
|
||||
}
|
||||
|
||||
I1 *ReadTextFile(I1 *filename,U8 *attr=NULL)
|
||||
{
|
||||
return ReadFile(filename,NULL,attr);
|
||||
}
|
||||
|
||||
|
||||
BoolU8 FindFile(I1 *filename,LTDirEntry *rde=NULL,
|
||||
BoolU4 dir_only=FALSE,BoolU4 file_only=FALSE,BoolU4 scan_parents=FALSE)
|
||||
{
|
||||
U8 cur_dir_cluster;
|
||||
BoolU4 result=FALSE;
|
||||
LTDirEntry de;
|
||||
LTFileAccess *fa=NewLTFileAccess(filename);
|
||||
if (fa) {
|
||||
cur_dir_cluster=NameToDirCluster(fa->p,Fs->cur_dir,TRUE);
|
||||
if (fa->p->type==PT_LT)
|
||||
result=FindLTFile(fa->p,cur_dir_cluster,fa->mask,
|
||||
&de,dir_only,file_only,TRUE);
|
||||
else if (fa->p->type==PT_ISO9660)
|
||||
result=FindISOFile(fa->p,cur_dir_cluster,fa->mask,
|
||||
&de,dir_only,file_only,TRUE);
|
||||
if (scan_parents) {
|
||||
while (!result && StrCmp(Fs->cur_dir,"/")) {
|
||||
Cd("..");
|
||||
cur_dir_cluster=NameToDirCluster(fa->p,Fs->cur_dir,TRUE);
|
||||
if (fa->p->type==PT_LT)
|
||||
result=FindLTFile(fa->p,cur_dir_cluster,fa->mask,
|
||||
&de,dir_only,file_only,TRUE);
|
||||
else if (fa->p->type==PT_ISO9660)
|
||||
result=FindISOFile(fa->p,cur_dir_cluster,fa->mask,
|
||||
&de,dir_only,file_only,TRUE);
|
||||
}
|
||||
}
|
||||
DelLTFileAccess(fa);
|
||||
}
|
||||
if (result && rde)
|
||||
MemCpy(rde,&de,sizeof(LTDirEntry));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
U8 WriteFile(I1 *filename,U1 *fbuf,
|
||||
U8 size,LTDate LTdatetime=0,U8 attr=0,BoolU4 raw=FALSE)
|
||||
{
|
||||
U8 c=0;
|
||||
SysHashEntry *temph;
|
||||
LTFileAccess *fa=NewLTFileAccess(filename);
|
||||
ArcCompressStruct *ac=NULL;
|
||||
I1 *absname=AbsoluteFileName(filename);
|
||||
if (fa) {
|
||||
if (fa->p->type==PT_LT)
|
||||
c=WriteLTFile(fa->p,Fs->cur_dir,fa->mask,
|
||||
fbuf,size,LTdatetime,attr,raw,&ac);
|
||||
if (temph=FindHashEntry(absname,adam_tss->hash_table,HTT_FILE)) {
|
||||
AFree(temph->user_data0);
|
||||
if (!raw && ac && attr & LT_ATTR_RESIDENT) {
|
||||
temph->user_data0=AMAllocIdentical(ac);
|
||||
temph->user_data1=size;
|
||||
} else {
|
||||
temph->user_data0=0;
|
||||
temph->type=HTT_INVALID;
|
||||
}
|
||||
} else if (!raw && ac && attr & LT_ATTR_RESIDENT) {
|
||||
temph=AMAllocZ(sizeof(SysHashEntry));
|
||||
temph->str=ANewStr(absname);
|
||||
temph->type=HTT_FILE;
|
||||
temph->use_cnt=0;
|
||||
temph->source_link=NULL;
|
||||
temph->user_data0=AMAllocIdentical(ac);
|
||||
temph->user_data1=size;
|
||||
AddSysHashEntry(temph,adam_tss->hash_table);
|
||||
}
|
||||
Free(ac);
|
||||
DelLTFileAccess(fa);
|
||||
}
|
||||
Free(absname);
|
||||
return c;
|
||||
}
|
||||
|
||||
void WriteTextFile(I1 *filename,I1 *st,U8 attr=0)
|
||||
{
|
||||
WriteFile(filename,st,StrLen(st),0,attr);
|
||||
}
|
||||
@@ -0,0 +1,338 @@
|
||||
void SelectDefaultDrive()
|
||||
{
|
||||
default_partition=DriveToPartition(default_drive);
|
||||
Fs->cur_partition=INVALID_PTR; //Null screws-up cache
|
||||
Fs->cur_dir=NewStr("/");
|
||||
ChangeDisk(':');
|
||||
}
|
||||
|
||||
BoolU8 CopySingleZ(I1 *f1,I1 *f2) //Just one file
|
||||
{
|
||||
U1 *file_buf=NULL;
|
||||
U8 size,attr=0;
|
||||
LTDirEntry de;
|
||||
|
||||
if (FindFile(f1,&de,FALSE,TRUE)) {
|
||||
file_buf=ReadFile(f1,&size,&attr);
|
||||
attr=FileAttr(f2,attr);
|
||||
if (file_buf) {
|
||||
coutln "Copying ",f1," to ",f2;
|
||||
WriteFile(f2,file_buf,size,de.datetime,attr);
|
||||
Free(file_buf);
|
||||
return TRUE;
|
||||
} else PutSysTextErr("ST_FILE_NOT_FOUND");
|
||||
} else PutSysTextErr("ST_FILE_NOT_FOUND");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#define COPY_BUF_BLKS 0x400
|
||||
BoolU8 CopySingle(I1 *f1,I1 *f2) //Just one file
|
||||
{
|
||||
U1 *buf;
|
||||
U8 cnt,n,size,attr1=FileAttr(f1),attr2=FileAttr(f2);
|
||||
LTFile *in_file=NULL,*out_file=NULL;
|
||||
U8 xsum=LT_XSUM,i,j;
|
||||
if (!StrCmp(f1,f2))
|
||||
return FALSE;
|
||||
if (attr1!=attr2)
|
||||
return CopySingleZ(f1,f2);
|
||||
buf=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS);
|
||||
if (attr1 & LT_ATTR_CONTIGUOUS)
|
||||
in_file=FOpen(f1,"rc");
|
||||
else
|
||||
in_file=FOpen(f1,"r");
|
||||
if (in_file) {
|
||||
size=FSize(in_file);
|
||||
cnt=(size+BLK_SIZE-1)>>BLK_SIZE_BITS;
|
||||
if (attr2 & LT_ATTR_CONTIGUOUS)
|
||||
out_file=FOpen(f2,"wc",cnt);
|
||||
else
|
||||
out_file=FOpen(f2,"w",cnt);
|
||||
if (out_file) {
|
||||
coutln "Copying ",f1," to ",f2;
|
||||
j=size;
|
||||
while (cnt) {
|
||||
if (cnt>COPY_BUF_BLKS) {
|
||||
n=COPY_BUF_BLKS;
|
||||
i=n<<BLK_SIZE_BITS;
|
||||
} else {
|
||||
n=cnt;
|
||||
i=j;
|
||||
}
|
||||
FRBlks(in_file, buf,LTFB_NEXT_BLK,n);
|
||||
xsum^=ArcCheckSum(buf,i);
|
||||
FWBlks(out_file,buf,LTFB_NEXT_BLK,n);
|
||||
cnt-=n;
|
||||
j-=n<<BLK_SIZE_BITS;
|
||||
}
|
||||
if (in_file->de.xsum &&
|
||||
in_file->de.xsum!=xsum)
|
||||
throw(EXCEPT_ARC_XSUM);
|
||||
out_file->de.xsum=xsum;
|
||||
out_file->flags|=LTF_USE_OLD_DATETIME;
|
||||
out_file->de.datetime=in_file->de.datetime;
|
||||
out_file->de.size=size;
|
||||
out_file->de.expanded_size=in_file->de.expanded_size;
|
||||
out_file->de.attr=FileAttr(f2,in_file->de.attr);
|
||||
FClose(out_file);
|
||||
FClose(in_file);
|
||||
Free(buf);
|
||||
return TRUE;
|
||||
} else PutSysTextErr("ST_FILE_NOT_FOUND");
|
||||
FClose(in_file);
|
||||
} else PutSysTextErr("ST_FILE_NOT_FOUND");
|
||||
Free(buf);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BoolU8 MkDir(I1 *filename)
|
||||
{
|
||||
U8 c,size,cur_dir_cluster;
|
||||
U1 *buf;
|
||||
BoolU4 result=FALSE;
|
||||
LTDirEntry *dLT;
|
||||
I1 *name;
|
||||
if (FindFile(filename,NULL,TRUE))
|
||||
return FALSE;
|
||||
LTFileAccess *fa=NewLTFileAccess(filename);
|
||||
if (fa) {
|
||||
if (*fa->mask) {
|
||||
if (!CheckFileName(fa->mask))
|
||||
PutSysTextErr("ST_INVALID_FILENAME");
|
||||
else {
|
||||
coutln "Make Directory:",filename;
|
||||
name=MStrUtil(fa->mask,
|
||||
SU_REMOVE_LEADING|SU_REMOVE_TRAILING|
|
||||
SU_DISCARD_PARITY|SU_REMOVE_CTRL_CHARS);
|
||||
size=fa->p->spc<<BLK_SIZE_BITS;
|
||||
buf=MAllocZ(size);
|
||||
cur_dir_cluster=NameToDirCluster(fa->p,Fs->cur_dir,TRUE);
|
||||
if (fa->p->type==PT_LT) {
|
||||
dLT=buf-offset(LTDirEntry.start);
|
||||
c=WriteFile(name,buf,size,0,LT_ATTR_DIR,FALSE);
|
||||
|
||||
dLT->attr=LT_ATTR_DIR|LT_ATTR_CONTIGUOUS;
|
||||
StrCpy(dLT->name,name);
|
||||
dLT->cluster=c;
|
||||
dLT->size=size;
|
||||
dLT->expanded_size=size;
|
||||
dLT->datetime=GetCurTimeLTDate;
|
||||
|
||||
dLT+=LT_DIR_ENTRY_SIZE;
|
||||
|
||||
dLT->attr=LT_ATTR_DIR|LT_ATTR_CONTIGUOUS;
|
||||
dLT->name[0]='.';
|
||||
dLT->name[1]='.';
|
||||
dLT->name[2]=0;
|
||||
dLT->cluster=cur_dir_cluster;
|
||||
dLT->size=0;
|
||||
dLT->expanded_size=0;
|
||||
dLT->datetime=GetCurTimeLTDate;
|
||||
|
||||
}
|
||||
WClusters(fa->p,buf,c,1,TRUE);
|
||||
Free(buf);
|
||||
Free(name);
|
||||
result=TRUE;
|
||||
}
|
||||
}
|
||||
DelLTFileAccess(fa);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void SysDel(I1 *wild,BoolU4 make_mask) //this is dangerous
|
||||
{
|
||||
LTFileAccess *fa=NewLTFileAccess(wild,make_mask);
|
||||
if (fa) {
|
||||
if (fa->p->type==PT_LT)
|
||||
DelLTFiles(fa->p,Fs->cur_dir,fa->mask,TRUE);
|
||||
DelLTFileAccess(fa);
|
||||
}
|
||||
}
|
||||
|
||||
void Format(I8 drive_letter,BoolU4 quick=TRUE,BoolU4 confirm=TRUE,U8 type=PT_LT)
|
||||
{
|
||||
LTPartition *p=DriveToPartition(drive_letter);
|
||||
if (confirm) {
|
||||
if (!AreYouSure)
|
||||
return;
|
||||
}
|
||||
if (!p) {
|
||||
PutSysTextErr("ST_INVALID_DRIVE");
|
||||
return;
|
||||
}
|
||||
if (type==PT_LT) {
|
||||
Drive(drive_letter);
|
||||
FormatLT(drive_letter,quick);
|
||||
InvalidateDiskCache(DriveToPartition(drive_letter),TRUE);
|
||||
Drive(drive_letter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ReadCDImage(I1 drive,I1 *out_name)
|
||||
{
|
||||
LTBlkDev *bdev=DriveToBlkDev(drive);
|
||||
LTPartition *p=DriveToPartition(drive);
|
||||
U1 *buf=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS);
|
||||
I1 *out_name2=DefaultExtension(out_name,"ISO");
|
||||
LTFile *f=FOpen(out_name2,"w");
|
||||
U8 n,dv,blk=0,cnt;
|
||||
InitBlkDev(bdev,TRUE);
|
||||
if (bdev->type!=LTBDT_ATAPI)
|
||||
throw(EXCEPT_BLKDEV,3);
|
||||
if (!out_name)
|
||||
out_name=default_iso_name;
|
||||
dv=bdev->blk_size>>BLK_SIZE_BITS;
|
||||
cnt=((p->size+dv-1)/dv)*dv;
|
||||
while (cnt) {
|
||||
if (cnt>COPY_BUF_BLKS)
|
||||
n=COPY_BUF_BLKS;
|
||||
else
|
||||
n=cnt;
|
||||
if (n>bdev->max_reads)
|
||||
n=bdev->max_reads;
|
||||
if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SOUND],0))
|
||||
Sound(bdev->read_freq);
|
||||
ATAPIReadBlks2(bdev,buf,blk/dv,n/dv);
|
||||
if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SOUND],0))
|
||||
Sound(0);
|
||||
FWBlks(f,buf,blk,n);
|
||||
cnt-=n;
|
||||
blk+=n;
|
||||
disk_reads+=n;
|
||||
}
|
||||
FClose(f);
|
||||
Free(buf);
|
||||
Free(out_name2);
|
||||
}
|
||||
|
||||
class LTDuelBuf
|
||||
{
|
||||
U1 *buf0,*buf1;
|
||||
U8 in_buf,out_buf,cnt;
|
||||
I1 *filename;
|
||||
LTBlkDev *CD_bdev;
|
||||
};
|
||||
|
||||
|
||||
void WriteCDImageTsk()
|
||||
{
|
||||
LTDuelBuf *d=Fs->user_data0;
|
||||
U1 *buf;
|
||||
U8 n,blk=0,cnt=d->cnt;
|
||||
LTFile *f;
|
||||
Preempt(ON);
|
||||
InitLocalTask; //needed for disk access
|
||||
if (FileAttr(d->filename)<_ATTR_CONTIGUOUS)
|
||||
f=FOpen(d->filename,"rc");
|
||||
else
|
||||
f=FOpen(d->filename,"r");
|
||||
while (cnt) {
|
||||
if (cnt>COPY_BUF_BLKS)
|
||||
n=COPY_BUF_BLKS;
|
||||
else
|
||||
n=cnt;
|
||||
if (n>d->CD_bdev->max_writes)
|
||||
n=d->CD_bdev->max_writes;
|
||||
buf=(d->in_buf & 1) ? d->buf1:d->buf0;
|
||||
while (d->in_buf>d->out_buf+1)
|
||||
SwapInNext;
|
||||
FRBlks(f,buf,blk,n);
|
||||
if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SOUND],0))
|
||||
Sound(d->CD_bdev->write_freq);
|
||||
d->in_buf++;
|
||||
cnt-=n;
|
||||
blk+=n;
|
||||
}
|
||||
FClose(f);
|
||||
}
|
||||
|
||||
void WriteCDImage(I1 drive,I1 *in_name)
|
||||
{
|
||||
LTDuelBuf *d=MAllocZ(sizeof(LTDuelBuf));
|
||||
U1 *buf;
|
||||
I1 *in_name2,*in_name3;
|
||||
U8 n,dv,blk=0,cnt;
|
||||
LTPartition *p=DriveToPartition(drive);
|
||||
LTBlkDev *bdev=p->bdev,*bdev2;
|
||||
TssStruct *tss;
|
||||
BoolU4 old_preempt;
|
||||
LTFile *f;
|
||||
|
||||
if (!in_name)
|
||||
in_name=default_iso_name;
|
||||
in_name3=DefaultExtension(in_name,"ISO");
|
||||
in_name2=AbsoluteFileName(in_name3);
|
||||
f=FOpen(in_name2,"r");
|
||||
if (!f) {
|
||||
Free(d);
|
||||
return;
|
||||
}
|
||||
|
||||
cnt=(FSize(f)+BLK_SIZE-1)>>BLK_SIZE_BITS;
|
||||
FClose(f);
|
||||
if (bdev->type!=LTBDT_ATAPI)
|
||||
throw(EXCEPT_BLKDEV,4);
|
||||
bdev2=DriveToBlkDev(*in_name2);
|
||||
if (bdev->irq==bdev2->irq) {
|
||||
coutln "Cannot Burn CD on same IDE controller as File.\r\n";
|
||||
throw(EXCEPT_BLKDEV,5);
|
||||
}
|
||||
|
||||
bdev->flags|=LTBDF_READ_ONLY_OVERRIDE;
|
||||
InitBlkDev(bdev,TRUE);
|
||||
dv=bdev->blk_size>>BLK_SIZE_BITS;
|
||||
if (p->size<cnt)
|
||||
p->size=cnt;
|
||||
|
||||
d->filename=in_name2;
|
||||
d->CD_bdev=bdev;
|
||||
d->buf0=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS);
|
||||
d->buf1=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS);
|
||||
d->cnt=cnt;
|
||||
|
||||
old_preempt=Preempt(OFF);
|
||||
tss=Spawn(&WriteCDImageTsk,"WRITE CD");
|
||||
tss->user_data0=d;
|
||||
|
||||
while (d->in_buf<=d->out_buf)
|
||||
SwapInNext;
|
||||
|
||||
if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SOUND],0))
|
||||
Sound(bdev->write_freq);
|
||||
IDEWaitForDrive(bdev);
|
||||
ATAPIWaitReady(bdev);
|
||||
|
||||
while (cnt) {
|
||||
if (cnt>COPY_BUF_BLKS)
|
||||
n=COPY_BUF_BLKS;
|
||||
else
|
||||
n=cnt;
|
||||
if (n>bdev->max_writes)
|
||||
n=bdev->max_writes;
|
||||
buf=(d->out_buf&1) ? d->buf1:d->buf0;
|
||||
while (d->in_buf<=d->out_buf)
|
||||
SwapInNext;
|
||||
ATAPIWriteBlks(bdev,buf,blk/dv,(n+dv-1)/dv);
|
||||
d->out_buf++;
|
||||
cnt-=n;
|
||||
blk+=n;
|
||||
disk_writes+=n;
|
||||
}
|
||||
ATAPISync(bdev);
|
||||
ATAPIClose(bdev);
|
||||
if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SOUND],0))
|
||||
Sound(0);
|
||||
bdev->flags&=~LTBDF_READ_ONLY_OVERRIDE;
|
||||
LBtr(&sema_irq_busy[bdev->irq],0);
|
||||
Free(d->buf0);
|
||||
Free(d->buf1);
|
||||
Free(d);
|
||||
Free(in_name2);
|
||||
Free(in_name3);
|
||||
Preempt(old_preempt);
|
||||
}
|
||||
|
||||
| ||||