LTCD_070816.ISO

This commit is contained in:
Terry A. Davis authored and minexew committed 2018-09-08 21:45:20 +02:00
1 parent d14bbc24f9
commit 0e9364ff4c
506 files changed
+157705 -41812

No files matched your search

+653
View File
@@ -0,0 +1,653 @@
void FreeLTFreeList(LTPartition *p,BoolU4 unlock)
{
LTFreeList *tempf,*tempf1;
try {
LockPartition(p);
if (tempf=p->next_free) {
while (tempf!=&p->next_free) {
tempf1=tempf->next;
AFree(tempf);
tempf=tempf1;
}
}
p->next_free=NULL;
if (unlock)
UnlockPartition(p);
} catch
if (unlock)
UnlockPartition(p);
}
void BuildLTFreeList(LTPartition *p,BoolU4 unlock)
{
LTFreeList *tempf;
U8 i,first=0,
max_cluster=(p->size+p->offset-p->data)/p->spc;
try {
LockPartition(p);
if (p->next_free)
FreeLTFreeList(p,FALSE);
p->next_free=&p->next_free;
p->last_free=&p->next_free;
while (first<max_cluster) {
i=0; //count free clusters
while (first+i<max_cluster) {
SetLTBuf(p,first+i);
if (Bt(p->cur_MAP_blk,(first+i)&(BLK_SIZE<<3-1)))
break;
else
i++;
}
if (i) {
tempf=AMAlloc(sizeof(LTFreeList));
tempf->size=i;
tempf->start=first;
InsQue(tempf,p->last_free);
}
first+=i+1;
}
if (unlock)
UnlockPartition(p);
} catch
if (unlock)
UnlockPartition(p);
}
void InitLTPartition(LTPartition *p,BoolU4 unlock)
{
LTBootStruct br;
try {
LockPartition(p);
RBlks(p,&br,p->offset,1,FALSE);
if (br.signature!=PT_LT ||
br.signature2!=0xAA55)
throw(EXCEPT_PARTITION,12);
p->type=PT_LT;
FreeLTFreeList(p,FALSE);
p->spc=br.sectors_per_cluster;
p->size=br.sectors;
p->data=p->offset+1+br.bitmap_sectors-p->spc;
p->root_cluster=br.root_cluster;
p->MAP1=p->offset+1;
p->MAP2=p->offset+1;
AllocMAPBuf(p,1);
if (unlock)
UnlockPartition(p);
} catch
if (unlock)
UnlockPartition(p);
}
void FormatLT(I1 drive_letter,BoolU4 quick=TRUE)
{
U1 *root_dir;
LTDirEntry *dLT;
LTBootStruct *br=MAllocZ(BLK_SIZE);
LTPartition *p=DriveToPartition(drive_letter);
U8 i,n;
try {
LockPartition(p);
// SetDriveType(drive_letter,PT_LT);
SetDriveType(drive_letter,PT_FAT32);
p->type=PT_LT;
br->U1s_per_sector=BLK_SIZE;
if (p->size<0x20000)
br->sectors_per_cluster=1;
else if (p->size<0x200000)
br->sectors_per_cluster=2;
else if (p->size<0x2000000)
br->sectors_per_cluster=4;
else if (p->size<0x20000000)
br->sectors_per_cluster=8;
else if (p->size<0x200000000)
br->sectors_per_cluster=16;
else
br->sectors_per_cluster=32;
br->signature=PT_LT;
br->signature2=0xAA55;
br->sectors=p->size;
n=br->sectors_per_cluster*(BLK_SIZE<<3);
n=(br->sectors+n-1)/n;
br->bitmap_sectors=n;
br->unique_id=BootTime;
br->root_cluster=0;
if (quick)
i=n+1;
else
i=p->size;
WZeroBlks(p,p->offset,i,FALSE);
WBlks(p,br,p->offset,1,FALSE);
InitLTPartition(p,FALSE);
AllocClusters(p,0,1,FALSE,FALSE); //Alloc #1
br->root_cluster=AllocClusters(p,0,1,FALSE,FALSE);
WBlks(p,br,p->offset,1,FALSE);
root_dir=MAllocZ(p->spc<<BLK_SIZE_BITS);
dLT=root_dir-offset(LTDirEntry.start);
dLT->attr=LT_ATTR_DIR|LT_ATTR_CONTIGUOUS;
dLT->name[0]='.';
dLT->cluster=br->root_cluster;
dLT->size=p->spc<<BLK_SIZE_BITS;
dLT->expanded_size=dLT->size;
dLT->datetime=GetCurTimeLTDate;
dLT+=LT_DIR_ENTRY_SIZE;
dLT->name[0]='.';
dLT->name[1]='.';
dLT->attr=LT_ATTR_DIR|LT_ATTR_CONTIGUOUS;
dLT->cluster=br->root_cluster;
dLT->datetime=GetCurTimeLTDate;
WBlks(p,root_dir,p->data+br->root_cluster*p->spc,p->spc,FALSE);
InitLTPartition(p,FALSE);
UnlockPartition(p);
} catch
UnlockPartition(p);
Free(br);
Free(root_dir);
}
BoolU8 FindLTFile(LTPartition *p,U8 cur_dir_cluster,I1 *name,LTDirEntry *result,
BoolU4 dir_only,BoolU4 file_only,BoolU4 unlock)
{
BoolU4 res=FALSE;
LTDirEntry *buf,*buf2,*ptr;
I1 dname[LT_MAX_FILENAME_LEN+1];
BoolU4 cont2=FALSE;
U1 ch;
MemSet(result,0,sizeof(LTDirEntry));
CheckLTPartition(p);
if (p->type!=PT_LT)
PutSysTextErr("ST_NOT_LT");
else if (!ToLTFilename(dname,name))
PutSysTextErr("ST_INVALID_FILENAME");
else {
try {
LockPartition(p);
buf2=MAlloc(p->spc<<BLK_SIZE_BITS);
RClusters(p,buf2,cur_dir_cluster,1,FALSE);
ptr=buf2-offset(LTDirEntry.start);
buf=MAlloc(ptr->size);
RClusters(p,buf,cur_dir_cluster,ptr->size>>BLK_SIZE_BITS/p->spc,FALSE);
Free(buf2);
ptr=buf-offset(LTDirEntry.start);
ptr->name[0]='.';
ptr->name[1]=0;
while (TRUE) {
ch=ptr->name[0];
if (!ch)
break;
else if (!(ptr->attr & LT_ATTR_DELETED)) {
if (dir_only && !(ptr->attr & LT_ATTR_DIR))
cont2=FALSE;
else if (file_only && ptr->attr & LT_ATTR_DIR)
cont2=FALSE;
else
cont2=TRUE;
if (cont2 && !StrCmp(dname,ptr->name)) {
MemCpy(&result->attr,&ptr->attr,LT_DIR_ENTRY_SIZE);
res=TRUE;
goto exit_this;
}
}
ptr+=LT_DIR_ENTRY_SIZE;
}
exit_this:
Free(buf);
if (unlock)
UnlockPartition(p);
} catch
if (unlock)
UnlockPartition(p);
}
return res;
}
U1 *ReadLTFile(LTPartition *p,I1 *cur_dir,I1 *filename,U8 *size,
U8 *attr,BoolU4 raw,ArcCompressStruct **ac2)
{
U1 *buf=NULL;
LTDirEntry de;
U8 c,cluster_size=p->spc<<BLK_SIZE_BITS,cluster_cnt;
ArcCompressStruct *ac;
U8 cur_dir_cluster=NameToDirCluster(p,cur_dir,TRUE);
CheckLTPartition(p);
if (size)
*size=0;
if (ac2)
*ac2=NULL;
if (attr)
*attr=0;
if (p->type!=PT_LT)
PutSysTextErr("ST_NOT_LT");
else {
try {
LockPartition(p);
if (FindLTFile(p,cur_dir_cluster,filename,&de,FALSE,TRUE,FALSE)) {
if (attr)
*attr=de.attr;
cluster_cnt=(de.size+cluster_size-1)/cluster_size;
buf=MAlloc(cluster_cnt*cluster_size+1);
c=de.cluster;
c=RClusters(p,buf,c,cluster_cnt,FALSE,TRUE);
if (de.xsum) {
if ((de.xsum^ArcCheckSum(buf,de.size))!=LT_XSUM)
throw(EXCEPT_ARC_XSUM);
}
if ((FileAttr(de.name) & LT_ATTR_COMPRESSED) && !raw) {
ac=buf;
if (attr)
*attr=FileAttr(de.name,*attr);
if (size)
*size=ac->expanded_size;
if (ac2) {
*ac2=ac;
buf=ExpandBuf(ac);
} else {
buf=ExpandBuf(ac);
Free(ac);
}
} else {
buf[de.size]=0; //Terminate
if (size)
*size=de.size;
}
if (attr)
*attr=FileAttr(de.name,*attr);
}
UnlockPartition(p);
} catch
UnlockPartition(p);
}
return buf;
}
BoolU8 CdLT(I1 *name,U8 cur_dir_cluster)
{
LTDirEntry de;
if (Fs->cur_partition->type!=PT_LT)
PutSysTextErr("ST_NOT_LT");
else {
if (FindLTFile(Fs->cur_partition,cur_dir_cluster,
name,&de,TRUE,FALSE,TRUE)) {
return TRUE;
} else {
cout name," ";
PutSysTextErr("ST_FILE_NOT_FOUND");
}
}
return FALSE;
}
void FreeLTClusters(LTPartition *p,U8 c,U8 cnt,BoolU4 unlock)
{
LTFreeList *tempf;
BoolU4 found=FALSE;
CheckLTPartition(p);
if (!c) return;
if (p->type!=PT_LT)
PutSysTextErr("ST_NOT_LT");
else {
try {
LockPartition(p);
if (!p->next_free)
BuildLTFreeList(p,FALSE);
tempf=p->next_free;
while (!found && tempf!=&p->next_free) {
if (tempf->start+tempf->size==c) {
tempf->size+=cnt;
found=TRUE;
} else if (c+cnt==tempf->start) {
tempf->size+=cnt;
tempf->start=c;
found=TRUE;
}
tempf=tempf->next;
}
if (!found) {
tempf=AMAlloc(sizeof(LTFreeList));
tempf->size=cnt;
tempf->start=c;
InsQue(tempf,p->last_free);
}
while (cnt--) {
SetLTBuf(p,c);
Btr(p->cur_MAP_blk,c&(BLK_SIZE<<3-1));
Bts(p->buffered_MAP_dirty_bits,0);
c++;
}
CleanMAPBuf(p);
if (unlock)
UnlockPartition(p);
} catch
if (unlock)
UnlockPartition(p);
}
}
U8 AllocLTClusters(LTPartition *p,U8 cnt, BoolU4 unlock)
{
LTFreeList *tempf,*best_free=NULL;
U8 i,first,best_size=MAX_U8;
if (!cnt)
Debugger;
try {
LockPartition(p);
if (!p->next_free)
BuildLTFreeList(p,FALSE);
tempf=p->next_free;
while (tempf!=&p->next_free) {
if (tempf->size>=cnt && tempf->size<best_size) {
best_free=tempf;
best_size=tempf->size;
if (tempf->size==cnt)
break;
}
tempf=tempf->next;
}
if (!best_free)
Debugger;
first=best_free->start;
for (i=0;i<cnt;i++) {
SetLTBuf(p,first+i);
Bts(p->cur_MAP_blk,(first+i)&(BLK_SIZE<<3-1));
Bts(p->buffered_MAP_dirty_bits,0);
}
CleanMAPBuf(p);
if (best_free->size-=cnt)
best_free->start+=cnt;
else {
RemQue(best_free);
AFree(best_free);
}
if (unlock)
UnlockPartition(p);
} catch
if (unlock)
UnlockPartition(p);
return first;
}
BoolU8 NewLTDirEntry2(LTPartition *p,I1 *cur_dir,LTDirEntry *de,BoolU4 free_old_chain,BoolU4 unlock)
{
LTDirEntry *buf,*buf2,*ptr,de2;
LTBootStruct *br;
U8 c,i=1,j=0,n=BLK_SIZE/LT_DIR_ENTRY_SIZE,dir_size;
BoolU4 written=FALSE;
U1 ch;
U8 cur_dir_cluster=NameToDirCluster(p,cur_dir,unlock);
I1 *temp,*parent_dir;
try {
de->attr|=LT_ATTR_CONTIGUOUS;
LockPartition(p);
buf2=MAlloc(p->spc<<BLK_SIZE_BITS);
RClusters(p,buf2,cur_dir_cluster,1,FALSE);
ptr=buf2-offset(LTDirEntry.start);
buf=MAlloc(ptr->size);
RClusters(p,buf,cur_dir_cluster,ptr->size>>BLK_SIZE_BITS/p->spc,FALSE);
dir_size=ptr->size;
ptr=buf-offset(LTDirEntry.start)+LT_DIR_ENTRY_SIZE;
Free(buf2);
while (TRUE) {
ch=ptr->name[0];
if (!ch) {
if (!written)
MemCpy(&ptr->start,&de->start,LT_DIR_ENTRY_SIZE);
if ((i+1)*LT_DIR_ENTRY_SIZE+j<<BLK_SIZE_BITS<dir_size)
WBlks(p,buf+j<<BLK_SIZE_BITS,
p->data+cur_dir_cluster*p->spc+j,1,FALSE);
else {
buf2=MAllocZ(dir_size+p->spc<<BLK_SIZE_BITS);
MemCpy(buf2,buf,dir_size);
FreeLTClusters(p,cur_dir_cluster,
dir_size/(p->spc<<BLK_SIZE_BITS),FALSE);
dir_size+=p->spc<<BLK_SIZE_BITS;
c=AllocClusters(p,0,dir_size/(p->spc<<BLK_SIZE_BITS),TRUE,FALSE);
Free(buf);
buf=buf2;
ptr=buf-offset(LTDirEntry.start);
ptr->size=dir_size;
ptr->expanded_size=dir_size;
ptr->cluster=c;
WClusters(p,buf,c,dir_size/(p->spc<<BLK_SIZE_BITS),FALSE);
if (cur_dir_cluster==p->root_cluster) {
br=MAllocZ(BLK_SIZE);
RBlks(p,br,p->offset,1,FALSE);
br->root_cluster=c;
WBlks(p,br,p->offset,1,FALSE);
Free(br);
p->root_cluster=c;
} else {
temp=NewStr(cur_dir);
parent_dir=NewStr(cur_dir);
RemoveLastSeg(parent_dir,"/",temp);
if (!*parent_dir) {
Free(parent_dir);
parent_dir=NewStr("/");
}
if (FindLTFile(p,NameToDirCluster(p,parent_dir,FALSE),
temp,&de2,TRUE,FALSE,FALSE)) {
de2.cluster=c;
de2.size=dir_size;
de2.expanded_size=dir_size;
//TODO: is this supposed to free old chain?
NewLTDirEntry2(p,parent_dir,&de2,FALSE,FALSE);
} else
Debugger;
Free(temp);
Free(parent_dir);
}
}
break;
} else if (ptr->attr & LT_ATTR_DELETED) {
if (!written) {
MemCpy(&ptr->start,&de->start,LT_DIR_ENTRY_SIZE);
WBlks(p,buf+j<<BLK_SIZE_BITS,
p->data+cur_dir_cluster*p->spc+j,1,FALSE);
written=TRUE;
}
} else {
if (!StrCmp(de->name,ptr->name)) {
if (free_old_chain)
FreeLTClusters(p,ptr->cluster,
(ptr->size+p->spc<<BLK_SIZE_BITS-1)/(p->spc<<BLK_SIZE_BITS),FALSE);
if (!written)
MemCpy(&ptr->start,&de->start,LT_DIR_ENTRY_SIZE);
else
ptr->attr|=LT_ATTR_DELETED;
WBlks(p,buf+j<<BLK_SIZE_BITS,
p->data+cur_dir_cluster*p->spc+j,1,FALSE);
break;
}
}
ptr+=LT_DIR_ENTRY_SIZE;
if (++i>=n) {
j++;
i=0;
}
}
Free(buf);
if (unlock)
UnlockPartition(p);
} catch
if (unlock)
UnlockPartition(p);
return FALSE;
}
BoolU8 DelLTFiles(LTPartition *p,I1 *cur_dir,I1 *wild,
BoolU4 del_dir=FALSE,BoolU4 print_msg=TRUE)
{
LTDirEntry *buf,*buf2,*ptr;
U8 i=0,j=0,n=BLK_SIZE/LT_DIR_ENTRY_SIZE;
U1 ch;
U8 cur_dir_cluster=NameToDirCluster(p,cur_dir,TRUE);
try {
LockPartition(p);
buf2=MAlloc(p->spc<<BLK_SIZE_BITS);
RClusters(p,buf2,cur_dir_cluster,1,FALSE);
ptr=buf2-offset(LTDirEntry.start);
buf=MAlloc(ptr->size);
RClusters(p,buf,cur_dir_cluster,ptr->size>>BLK_SIZE_BITS/p->spc,FALSE);
Free(buf2);
ptr=buf-offset(LTDirEntry.start);
ptr->name[0]='.';
ptr->name[1]=0;
while (TRUE) {
ch=ptr->name[0];
if (!ch)
break;
else if (!(ptr->attr & LT_ATTR_DELETED) && ch!='.' && (del_dir ||
!(ptr->attr & LT_ATTR_DIR))) {
if (WildFileNameList(wild,ptr->name)) {
if (print_msg)
coutln SysText("ST_DELETE"),ptr->name;
ptr->attr|=LT_ATTR_DELETED;
WBlks(p,buf+j<<BLK_SIZE_BITS,
p->data+cur_dir_cluster*p->spc+j,1,FALSE);
FreeLTClusters(p,ptr->cluster,
(ptr->size+p->spc<<BLK_SIZE_BITS-1)/(p->spc<<BLK_SIZE_BITS),FALSE);
}
}
ptr+=LT_DIR_ENTRY_SIZE;
if (++i>=n) {
j++;
i=0;
}
}
Free(buf);
UnlockPartition(p);
} catch
UnlockPartition(p);
return FALSE;
}
U8 WriteLTFile(LTPartition *p,I1 *cur_dir,I1 *name,U1 *buf,U8 size,
LTDate LTdatetime,U8 attr,BoolU4 raw,
ArcCompressStruct **ac2)
{
LTDirEntry de;
U8 c=0;
U8 flags=0,cluster_cnt,
cluster_size=p->spc<<BLK_SIZE_BITS;
ArcCompressStruct *ac=NULL;
BoolU4 contiguous;
U8 cur_dir_cluster=NameToDirCluster(p,cur_dir,TRUE);
MemSet(&de,0,sizeof(LTDirEntry));
if (ac2) *ac2=NULL;
if (!LTdatetime)
LTdatetime=GetCurTimeLTDate;
if (p->type!=PT_LT)
PutSysTextErr("ST_NOT_LT");
else if (!ToLTFilename(de.name,name))
PutSysTextErr("ST_INVALID_FILENAME");
else {
DelLTFiles(p,cur_dir,de.name,FALSE,FALSE);
attr=FileAttr(name,attr);
attr|=LT_ATTR_CONTIGUOUS;
contiguous=TRUE;
de.expanded_size=size;
if ((attr & LT_ATTR_COMPRESSED) && !raw) {
ac=CompressBuf(buf,size,flags);
size=ac->compressed_size;
buf=ac;
}
de.size=size;
de.xsum=ArcCheckSum(buf,size)^LT_XSUM;
cluster_cnt=(size+cluster_size-1)/cluster_size;
if (cluster_cnt)
c=AllocClusters(p,0,cluster_cnt,contiguous,TRUE);
else
c=INVALID_CLUSTER;
de.cluster=c;
de.attr=attr;
de.datetime=LTdatetime;
if (cluster_cnt)
WClusters(p,buf,c,cluster_cnt,TRUE,TRUE);
NewLTDirEntry2(p,cur_dir,&de,TRUE,TRUE);
if (ac2)
*ac2=ac;
else
Free(ac);
}
return c;
}
LTDirEntry *FindLTFiles(I1 *wild,U8 fuf_flags,LTDirEntry *parent=NULL)
{
LTPartition *p=Fs->cur_partition;
LTDirEntry *buf,*buf2,*ptr;
U8 cur_dir_cluster=NameToDirCluster(p,Fs->cur_dir,FALSE);
U1 ch;
LTDirEntry *result=NULL,*tempm;
LockPartition(p);
buf2=MAlloc(p->spc<<BLK_SIZE_BITS);
RClusters(p,buf2,cur_dir_cluster,1,FALSE);
ptr=buf2-offset(LTDirEntry.start);
buf=MAlloc(ptr->size);
RClusters(p,buf,cur_dir_cluster,ptr->size>>BLK_SIZE_BITS/p->spc,FALSE);
Free(buf2);
ptr=buf-offset(LTDirEntry.start);
ptr->name[0]='.';
ptr->name[1]=0;
ptr+=LT_DIR_ENTRY_SIZE;
ptr->cluster=NameToParentDirCluster(p,Fs->cur_dir,FALSE);
ptr-=LT_DIR_ENTRY_SIZE;
while (TRUE) {
ch=ptr->name[0];
if (!ch)
break;
else if (!(ptr->attr & LT_ATTR_DELETED)) {
tempm=MAllocZ(sizeof(LTDirEntry));
MemCpy(&tempm->start,&ptr->start,LT_DIR_ENTRY_SIZE);
tempm->parent=parent;
if (Bt(&fuf_flags,FUf_RECURSE) && tempm->attr & LT_ATTR_DIR && tempm->name[0]!='.') {
tempm->next=result;
result=tempm;
tempm->full_name=AbsoluteDirName(tempm->name);
UnlockPartition(p);
Cd(tempm->name);
tempm->sub=FindLTFiles(wild,fuf_flags,tempm);
Cd("..");
LockPartition(p);
} else if ((!(tempm->attr & LT_ATTR_DIR) && !Bt(&fuf_flags,FUf_JUST_DIRS)
|| !Bt(&fuf_flags,FUf_RECURSE)) &&
!(Bt(&fuf_flags,FUf_RECURSE) && tempm->name[0]=='.') &&
WildFileNameList(wild,tempm->name)) {
tempm->next=result;
result=tempm;
tempm->full_name=AbsoluteFileName(tempm->name);
} else
DelLTDirEntry(tempm);
}
ptr+=LT_DIR_ENTRY_SIZE;
}
Free(buf);
UnlockPartition(p);
return result;
}