Files
TempleOS-Rijn/LT/ADAM/DISK10.CPZ
T
2018-09-08 21:45:17 +02:00

821 lines
22 KiB
Plaintext

public BoolU4 Copy(I1 *f1,I1 *f2=".")
{
BoolU4 result=TRUE;
LTFileAccess *fa;
LTDirEntry *tempm,*tempm1;
U8 my_flags=0;
if (!(tempm=FindFiles(f1,&my_flags)))
return FALSE;
if (IsDir(f2)) {
fa=NewLTFileAccess(f2,TRUE);
if (fa) {
while (tempm) {
tempm1=tempm->next;
if (!(tempm->attr & LT_ATTR_DIR)) {
if (!CopySingle(tempm->full_name,tempm->name))
result=FALSE;
}
DelLTDirEntry(tempm);
tempm=tempm1;
}
DelLTFileAccess(fa);
}
return result;
} else
return CopySingle(f1,f2);
}
public BoolU4 Move(I1 *f1,I1 *f2)
{
if (Copy(f1,f2)) {
Del(f1);
return TRUE;
}
return FALSE;
}
U8 PutCopyTree(LTDirEntry *tempm,U8 src_dir_len,U8 dst_dir_len,I1 *dst_dir)
{
U8 result=0;
I1 *st;
while (tempm) {
st=MAlloc(StrLen(tempm->full_name)+dst_dir_len+2);
MemCpy(st,dst_dir,dst_dir_len);
StrCpy(st+dst_dir_len,tempm->full_name+src_dir_len);
if (tempm->attr & LT_ATTR_DIR) {
MkDir(st);
if (IsDir(st) && tempm->sub)
result+=PutCopyTree(tempm->sub,src_dir_len,dst_dir_len,dst_dir);
} else
if (CopySingle(tempm->full_name,st))
result++;
Free(st);
tempm=tempm->next;
}
return result;
}
public U8 CopyTree(I1 *src_mask,I1 *dst_mask)
{ //returns count of copied files (not dirs)
LTFileAccess *fa;
LTDirEntry *tempm=NULL;
U8 result=0,i1,i2,my_flags=(1<<FUf_RECURSE);
I1 *st1,*st2;
fa=NewLTFileAccess(src_mask,TRUE);
if (fa) {
tempm=SysFindFiles(fa->mask,&my_flags);
st1=CurDir;
DelLTFileAccess(fa);
i1=StrLen(st1);
if (i1==3) i1--;
fa=NewLTFileAccess(dst_mask,TRUE,TRUE);
if (fa) {
st2=CurDir;
i2=StrLen(st2);
if (i2==3) i2--;
result=PutCopyTree(tempm,i1,i2,st2);
DelLTFileAccess(fa);
Free(st2);
}
DelLTDirList(tempm);
Free(st1);
}
return result;
}
void DoDelTree(LTDirEntry *tempm1)
{
U8 result=0;
LTDirEntry *tempm2;
while (tempm1) {
tempm2=tempm1->next;
if (tempm1->attr & LT_ATTR_DIR) {
if (tempm1->sub)
result+=DoDelTree(tempm1->sub);
SysDel(tempm1->full_name,TRUE);
}
DelLTDirEntry(tempm1);
tempm1=tempm2;
}
}
public BoolU4 DelTree(I1 *mask)
{
U8 my_flags=(1<<FUf_RECURSE);
if (!IsDir(mask)) {
coutln "Not a Directory";
return FALSE;
}
DoDelTree(FindFiles(mask,&my_flags));
SysDel(mask,TRUE);
SysDel(mask,FALSE);
return TRUE;
}
void DoDelMask(LTDirEntry *tempm1)
{
LTDirEntry *tempm2;
while (tempm1) {
tempm2=tempm1->next;
if (tempm1->attr & LT_ATTR_DIR) {
if (tempm1->sub)
DoDelMask(tempm1->sub);
} else
Del(tempm1->full_name);
DelLTDirEntry(tempm1);
tempm1=tempm2;
}
}
public BoolU4 DelMask(I1 *mask)
{ //Purges select filetypes from tree
U8 my_flags=(1<<FUf_RECURSE);
if (IsDir(mask)) {
coutln "Not a Mask";
return FALSE;
}
DoDelMask(FindFiles(mask,&my_flags));
return TRUE;
}
void TouchFile(I1 *filename,I1 *attr) //LTust one file
{
U1 *temp_st=NewString(filename),
*cur_dir=NewString(filename);
LTPartition *p=DriveToPartition(*filename);
FlagsStruct f;
LTDirEntry de;
I1 buf[64];
if (FindFile(filename,&de,FALSE,TRUE)) {
if (!StrCmp(attr,"+?"))
PrintF("%-32ts %s\r\n",filename,SPrintFFlags(buf,"ST_FILE_ATTRS",de.attr));
else {
GetFFlags(&f,"ST_FILE_ATTRS",attr);
RemoveFirstSeg(cur_dir,":",temp_st);
RemoveLastSeg(cur_dir,"/",temp_st);
if (!*cur_dir)
StrCpy(cur_dir,"/");
de.attr=de.attr&f.off|f.on;
de.datetime=GetCurTimeLTDate;
NewLTDirEntry(p,cur_dir,&de,FALSE);
}
} else PutSysText("ST_FILE_NOT_FOUND");
}
void TouchList(LTDirEntry *tempm1,I1 *attr)
{
LTDirEntry *tempm2;
while (tempm1) {
tempm2=tempm1->next;
if (tempm1->attr & LT_ATTR_DIR) {
if (tempm1->sub) {
coutln SysText("ST_SCANNING_DIRECTORY"),tempm1->full_name;
TouchList(tempm1->sub,attr);
}
} else
TouchFile(tempm1->full_name,attr);
DelLTDirEntry(tempm1);
tempm1=tempm2;
}
}
//Attr "+?" =show
// "+T" = resident
//flags "+r"=recurse
public void Touch(I1 *wild,I1 *attr="+?",I1 *flags="")
{
FlagsStruct f;
GetFFlags(&f,"ST_FILE_UTIL_FLAGS",flags);
TouchList(FindFiles(wild,&f.on),attr);
}
void FillBigEndianU2(U2 *dst,U2 w)
{
U2 *src=&w;
dst->u1[0]=src->u1[1];
dst->u1[1]=src->u1[0];
}
void FillBigEndianU4(U4 *dst,U8 d)
{
U8 *src=&d;
dst->u1[0]=src->u1[3];
dst->u1[1]=src->u1[2];
dst->u1[2]=src->u1[1];
dst->u1[3]=src->u1[0];
}
void FillU2Palindrome(U2Palindrome *dst,U2 w)
{
FillBigEndianU2(&dst->big,w);
dst->little=w;
}
void FillU4Palindrome(U4Palindrome *dst,U8 d)
{
FillBigEndianU4(&dst->big,d);
dst->little=d;
}
class CCdUserData
{
U8 location,path_entry_num,
short_dir_blks,long_dir_blks;
};
U8 DoCreateCDFile(LTFile *out_file,LTDirEntry *tempm,
ISODirEntry *tempi,ISODirEntry *tempi2,
U8 *cur_blk,
LTDirEntry *parent,BoolU4 write)
{
CCdUserData *tempc;
LTDirEntry *tempm1,*tempm2;
LTFile *in_file;
U1 *buf=MAlloc(CD_BLK_SIZE),*ptr1,*ptr2;
ISODirEntry *dir_blk_buf=MAllocZ(CD_BLK_SIZE*128),
*de=dir_blk_buf,*de1;
ISODirEntry *dir_blk_buf2=MAllocZ(CD_BLK_SIZE*128),
*de2=dir_blk_buf2,*de12;
U8 i,l;
tempc=parent->user_data;
de->length=sizeof(ISODirEntry)-1;
de->ext_attr_length=0;
FillU2Palindrome(&de->volume_sequence_num,1);
LTDateToISO(&de->date,tempm->datetime);
de->flags=ISO_ATTR_DIR;
de->name_len=1;
de->name=0;
de->length+=de->name_len;
de+=de->length;
de->length=sizeof(ISODirEntry)-1;
de->ext_attr_length=0;
FillU4Palindrome(&de->location,tempc->location);
FillU4Palindrome(&de->size,tempc->short_dir_blks*CD_BLK_SIZE);
FillU2Palindrome(&de->volume_sequence_num,1);
LTDateToISO(&de->date,parent->datetime);
de->flags=ISO_ATTR_DIR;
de->name_len=1;
de->name=1;
de->length+=de->name_len;
de+=de->length;
de2->length=sizeof(ISODirEntry)-1;
de2->ext_attr_length=0;
FillU2Palindrome(&de2->volume_sequence_num,1);
LTDateToISO(&de2->date,tempm->datetime);
de2->flags=ISO_ATTR_DIR;
de2->name_len=1;
de2->name=0;
de2->length=de2->length+de2->name_len;
de2+=de2->length;
de2->length=sizeof(ISODirEntry)-1;
de2->ext_attr_length=0;
FillU4Palindrome(&de2->location,tempc->location+tempc->short_dir_blks);
FillU4Palindrome(&de2->size,tempc->long_dir_blks*CD_BLK_SIZE);
FillU2Palindrome(&de2->volume_sequence_num,1);
LTDateToISO(&de2->date,parent->datetime);
de2->flags=ISO_ATTR_DIR;
de2->name_len=1;
de2->name=1;
de2->length+=de2->name_len;
de2+=de2->length;
tempm1=tempm->sub;
while (tempm1) {
tempm2=tempm1->next;
if (!write) tempm1->user_data=MAllocZ(sizeof(CCdUserData));
de1=de;
de12=de2;
if (tempm1->attr & LT_ATTR_DIR) {
l=DoCreateCDFile(out_file,tempm1,de,de2,cur_blk,tempm,write);
de+=sizeof(ISODirEntry)-1+l;
de2+=sizeof(ISODirEntry)-1+l<<1;
} else {
tempc=tempm1->user_data;
de->length=sizeof(ISODirEntry)-1;
de->ext_attr_length=0;
FillU4Palindrome(&de->location,*cur_blk);
tempc->location=*cur_blk;
if (write)
coutln *cur_blk,":",tempm1->full_name;
FillU4Palindrome(&de->size,tempm1->size);
FillU2Palindrome(&de->volume_sequence_num,1);
LTDateToISO(&de->date,tempm1->datetime);
de->flags=0;
de->name_len=StrLen(tempm1->name);
StrCpy(&de->name,tempm1->name);
de->length=de->length+de->name_len;
de+=de->length;
de2->length=sizeof(ISODirEntry)-1;
de2->ext_attr_length=0;
FillU4Palindrome(&de2->location,*cur_blk);
FillU4Palindrome(&de2->size,tempm1->size);
FillU2Palindrome(&de2->volume_sequence_num,1);
LTDateToISO(&de2->date,tempm1->datetime);
de2->flags=0;
de2->name_len=StrLen(tempm1->name)<<1;
ptr1=&de2->name;
ptr2=&tempm1->name;
for (i=0;i<de2->name_len;i=i+2) {
ptr1++;
*ptr1++=*ptr2++;
}
de2->length+=de2->name_len;
de2+=de2->length;
in_file=FOpen(tempm1->full_name,"r");
for (i=0;i<(FSize(in_file)+CD_BLK_SIZE-1)/CD_BLK_SIZE;i++) {
l=4;
if ((i+1)<<2>(FSize(in_file)+BLK_SIZE-1)/BLK_SIZE) {
l=((FSize(in_file)+BLK_SIZE-1)/BLK_SIZE)%4;
MemSet(buf,0,CD_BLK_SIZE);
}
if (write) {
FRBlks(in_file,buf,i<<2,l);
FWBlks(out_file,buf,(*cur_blk)<<2,l);
}
*cur_blk+=1;
}
FClose(in_file);
}
if ((de1-dir_blk_buf)/CD_BLK_SIZE!=
(de -dir_blk_buf)/CD_BLK_SIZE) {
i=de1->length;
MemCpy(buf,de1,i);
MemSet(de1,0,i);
de=dir_blk_buf+((de-dir_blk_buf)/CD_BLK_SIZE)*CD_BLK_SIZE;
MemCpy(de,buf,i);
de+=i;
}
if ((de12-dir_blk_buf2)/CD_BLK_SIZE!=
(de2 -dir_blk_buf2)/CD_BLK_SIZE) {
i=de12->length;
MemCpy(buf,de12,i);
MemSet(de12,0,i);
de2=dir_blk_buf2+((de2-dir_blk_buf2)/CD_BLK_SIZE)*CD_BLK_SIZE;
MemCpy(de2,buf,i);
de2+=i;
}
tempm1=tempm2;
}
tempc=tempm->user_data;
tempi->length=sizeof(ISODirEntry)-1;
tempi->ext_attr_length=0;
tempi->flags=ISO_ATTR_DIR;
if (!tempm->name[0]) {
tempi->name_len=1;
tempi->name=1;
} else {
tempi->name_len=StrLen(tempm->name);
StrCpy(&tempi->name,tempm->name);
}
tempi->length+=tempi->name_len;
l=de+1-dir_blk_buf;
l=(l+CD_BLK_SIZE-1)/CD_BLK_SIZE;
FillU4Palindrome(&tempi->size,l*CD_BLK_SIZE);
FillU4Palindrome(&tempi->location,*cur_blk);
tempc->short_dir_blks=l;
tempc->location=*cur_blk;
FillU4Palindrome(&dir_blk_buf->size,l*CD_BLK_SIZE);
FillU4Palindrome(&dir_blk_buf->location,*cur_blk);
FillU2Palindrome(&tempi->volume_sequence_num,1);
LTDateToISO(&tempi->date,tempm->datetime);
if (write)
coutln *cur_blk,":",tempm->full_name;
if (write)
FWBlks(out_file,dir_blk_buf,(*cur_blk)<<2,l<<2);
*cur_blk+=l;
tempi2->length=sizeof(ISODirEntry)-1;
tempi2->ext_attr_length=0;
tempi2->flags=ISO_ATTR_DIR;
if (!tempm->name[0]) {
tempi2->name_len=1;
tempi->name=1;
} else {
tempi2->name_len=StrLen(tempm->name)<<1;
ptr1=&tempi2->name;
ptr2=&tempm->name;
for (i=0;i<tempi2->name_len;i=i+2) {
ptr1++;
*ptr1++=*ptr2++;
}
}
tempi2->length+=tempi2->name_len;
l=de2+1-dir_blk_buf2;
l=(l+CD_BLK_SIZE-1)/CD_BLK_SIZE;
FillU4Palindrome(&tempi2->size,l*CD_BLK_SIZE);
FillU4Palindrome(&tempi2->location,*cur_blk);
tempc->long_dir_blks=l;
FillU4Palindrome(&dir_blk_buf2->size,l*CD_BLK_SIZE);
FillU4Palindrome(&dir_blk_buf2->location,*cur_blk);
FillU2Palindrome(&tempi2->volume_sequence_num,1);
LTDateToISO(&tempi2->date,tempm->datetime);
if (write)
coutln *cur_blk,":",tempm->full_name;
if (write)
FWBlks(out_file,dir_blk_buf2,(*cur_blk)<<2,l<<2);
*cur_blk+=l;
Free(dir_blk_buf);
Free(dir_blk_buf2);
Free(buf);
return tempi->name_len;
}
U8 CDTableLength(LTDirEntry *tempm,U8 *size1,U8 *size2,U8 cur_depth)
//returns depth
{
LTDirEntry *tempm1=tempm->sub;
U8 max_depth=cur_depth,i;
while (tempm1) {
if (tempm1->attr & LT_ATTR_DIR) {
*size1+=sizeof(ISOPathTableEntry)-2+((StrLen(tempm1->name)+1) & -0x2);
*size2+=sizeof(ISOPathTableEntry)-2+StrLen(tempm1->name)<<1;
i=CDTableLength(tempm1,size1,size2,cur_depth+1);
if (i>max_depth) max_depth=i;
}
tempm1=tempm1->next;
}
return max_depth;
}
void CDFillPathTable(LTDirEntry *tempm,
ISOPathTableEntry *itabbuf,ISOPathTableEntry *itabbuf2,
U8 parent_entry_num,BoolU4 big_endian,U8 *first_free,I8 cur_level,I8 output_level)
{
I1 *ptr1,*ptr2;
U8 i;
ISOPathTableEntry *tabbuf=*itabbuf;
ISOPathTableEntry *tabbuf2=*itabbuf2;
LTDirEntry *tempm1=tempm->sub,*tempm2;
CCdUserData *tempc;
if (cur_level==output_level) {
while (tempm1) {
if (tempm1->attr & LT_ATTR_DIR) {
tempc=tempm1->user_data;
tempc->path_entry_num=*first_free;
tabbuf->name_len=StrLen(tempm1->name);
if (big_endian) {
FillBigEndianU4(&tabbuf->blk,tempc->location);
FillBigEndianU2(&tabbuf->parent_entry_num,parent_entry_num);
} else {
tabbuf->blk=tempc->location;
tabbuf->parent_entry_num=parent_entry_num;
}
StrCpy(&tabbuf->name,tempm1->name);
tabbuf+=sizeof(ISOPathTableEntry)-2+
((StrLen(tempm1->name)+1) & -0x2);
tabbuf2->name_len=StrLen(tempm1->name)<<1;
if (big_endian) {
FillBigEndianU4(&tabbuf2->blk,tempc->location+tempc->short_dir_blks);
FillBigEndianU2(&tabbuf2->parent_entry_num,parent_entry_num);
} else {
tabbuf2->blk=tempc->location+tempc->short_dir_blks;
tabbuf2->parent_entry_num=parent_entry_num;
}
ptr1=&tabbuf2->name;
ptr2=&tempm1->name;
for (i=0;i<tabbuf2->name_len;i=i+2) {
ptr1++;
*ptr1++=*ptr2++;
}
tabbuf2+=sizeof(ISOPathTableEntry)-2+
StrLen(tempm1->name)<<1;
*first_free+=1;
}
tempm1=tempm1->next;
}
*itabbuf=tabbuf;
*itabbuf2=tabbuf2;
}
tempm1=tempm->sub;
while (tempm1) {
tempm2=tempm1->next;
if (tempm1->attr & LT_ATTR_DIR) {
tempc=tempm1->user_data;
CDFillPathTable(tempm1,itabbuf,itabbuf2,tempc->path_entry_num,
big_endian,first_free,cur_level+1,output_level);
}
tempm1=tempm2;
}
}
class ElTorito
{
U2 w[16];
U1 bootable; //88=bootable 00=not bootable
U1 media_type; //0=no emulation 4=hard disk
U2 load_seg; //0000->07C0
U1 sys_type;
U1 zero;
U2 sector_cnt;
U4 load_rba; //start address of virtual disk
U1 zero2[20];
};
public U8 CreateCDFile(I1 *filename,I1 src_drive,
I1 *bootfile=NULL)
{
ISOPrimaryDescriptor *iso =MAllocZ(CD_BLK_SIZE),
*iso1=MAllocZ(CD_BLK_SIZE),
*iso2=MAllocZ(CD_BLK_SIZE),
*iso3=MAllocZ(CD_BLK_SIZE);
LTDirEntry *rootdir=MAllocZ(sizeof(LTDirEntry));
U8 my_flags=(1<<FUf_RECURSE);
U8 cur_blk=0,bsize,tabsize,tabsize2,first_free,max_depth;
U4 *d;
I1 mask[8];
I1 *filename2=DefaultExtension(filename,"ISO");
ElTorito *et=MAllocZ(CD_BLK_SIZE);
U1 *buf=MAllocZ(CD_BLK_SIZE),
*bootfile_buf=NULL;
ISOPathTableEntry *tabbuf=NULL,*tabbuf2=NULL,
*itabbuf,*itabbuf2;
BoolU4 okay=TRUE;
U8 i,j;
LTFile *out_file=NULL;
ISODirEntry *tempi;
CCdUserData *tempc;
SPrintF(mask,"%c:/*",src_drive);
if (bootfile)
bootfile_buf=ReadFile(bootfile,&bsize);
rootdir->attr=LT_ATTR_DIR;
rootdir->sub=FindFiles(mask,&my_flags);
rootdir->datetime=GetCurTimeLTDate;
rootdir->user_data=MAllocZ(sizeof(CCdUserData));
tempc=rootdir->user_data;
tempc->path_entry_num=1;
if (okay) {
cur_blk=CD_FILE_OFFSET>>2;
if (bootfile_buf)
cur_blk+=2;
DoCreateCDFile(out_file,rootdir,
&iso->root_directory_record,
&iso2->root_directory_record,
&cur_blk,rootdir,FALSE);
tabsize=sizeof(ISOPathTableEntry);
tabsize2=sizeof(ISOPathTableEntry);
max_depth=CDTableLength(rootdir,&tabsize,&tabsize2,1);
FillU4Palindrome(&iso->path_table_size,tabsize);
FillU4Palindrome(&iso2->path_table_size,tabsize2);
tabsize=(tabsize+CD_BLK_SIZE-1)/CD_BLK_SIZE;
cur_blk+=tabsize<<1;
tabsize2=(tabsize2+CD_BLK_SIZE-1)/CD_BLK_SIZE;
cur_blk+=tabsize2<<1;
}
if (okay) {
if (FileAttr(filename2) & LT_ATTR_CONTIGUOUS)
out_file=FOpen(filename2,"wc",cur_blk<<2);
else
out_file=FOpen(filename2,"w",cur_blk<<2);
if (!out_file)
okay=FALSE;
}
if (okay) {
cur_blk=0;
while (cur_blk<CD_FILE_OFFSET>>2) {
FWBlks(out_file,buf,cur_blk<<2,4);
cur_blk++;
}
iso->type=ISOT_PRIMARY_VOLUME_DESC;
StrCpy(iso->id,"CD001");
iso->version=1;
FillU2Palindrome(&iso->volume_set_size,1);
FillU2Palindrome(&iso->volume_sequence_number,1);
FillU2Palindrome(&iso->logical_block_size,CD_BLK_SIZE);
iso->file_structure_version=1;
iso2->type=ISOT_SUPPLEMENTARY_DESC;
StrCpy(iso2->id,"CD001");
iso2->version=1;
FillU2Palindrome(&iso2->volume_set_size,1);
FillU2Palindrome(&iso2->volume_sequence_number,1);
FillU2Palindrome(&iso2->logical_block_size,CD_BLK_SIZE);
iso2->file_structure_version=1;
iso1->type=ISOT_BOOT_RECORD;
StrCpy(iso1->id,"CD001");
iso1->version=1;
StrCpy(iso1+7,"EL TORITO SPECIFICATION");
cur_blk=CD_FILE_OFFSET>>2;
if (bootfile_buf) {
d=iso1+0x47;
*d=cur_blk;
et->w[0]=1;
StrCpy(&et->w[2],"LoseThos");
et->w[15]=0xAA55;
j=0;
for (i=0;i<16;i++) //Checksum
j+=et->w[i];
et->w[14]=-j;
if (bootfile_buf)
et->bootable=0x88;
et->media_type=0; //0=no emu 2=1.44meg 4=hard drive
et->sector_cnt=4;
et->load_rba=cur_blk+1;
coutln cur_blk,": Pre Boot Blk";
FWBlks(out_file,et,cur_blk<<2,4);
cur_blk++;
coutln cur_blk,": Boot Blk";
FWBlks(out_file,bootfile_buf,cur_blk<<2,4);
cur_blk++;
}
DoCreateCDFile(out_file,rootdir,
&iso->root_directory_record,
&iso2->root_directory_record,
&cur_blk,rootdir,TRUE);
tabbuf=MAllocZ(tabsize*CD_BLK_SIZE);
iso->type_l_path_table=cur_blk;
tabbuf->name_len=2; //Fill-in adam entry
tempi=&iso->root_directory_record;
tabbuf->blk=tempi->location.little;
tabbuf->parent_entry_num=1;
tabbuf2=MAllocZ(tabsize2*CD_BLK_SIZE);
iso2->type_l_path_table=cur_blk+tabsize;
tabbuf2->name_len=2; //Fill-in adam entry
tempi=&iso2->root_directory_record;
tabbuf2->blk=tempi->location.little;
tabbuf2->parent_entry_num=1;
itabbuf=tabbuf+sizeof(ISOPathTableEntry);
itabbuf2=tabbuf2+sizeof(ISOPathTableEntry);
first_free=2;
for (i=1;i<=max_depth;i++)
CDFillPathTable(rootdir,&itabbuf,&itabbuf2,
1,FALSE,&first_free,1,i);
coutln cur_blk,": Path Table 0";
FWBlks(out_file,tabbuf,cur_blk<<2,tabsize<<2);
cur_blk+=tabsize;
coutln cur_blk,": Path Table 1";
FWBlks(out_file,tabbuf2,cur_blk<<2,tabsize2<<2);
cur_blk+=tabsize2;
MemSet(tabbuf,0,tabsize*CD_BLK_SIZE);
FillBigEndianU4(&iso->type_m_path_table,cur_blk);
tabbuf->name_len=2; //Fill-in adam entry
tempi=&iso->root_directory_record;
tabbuf->blk=tempi->location.big;
FillBigEndianU2(&tabbuf->parent_entry_num,1);
MemSet(tabbuf2,0,tabsize2*CD_BLK_SIZE);
FillBigEndianU4(&iso2->type_m_path_table,cur_blk+tabsize);
tabbuf2->name_len=2; //Fill-in adam entry
tempi=&iso2->root_directory_record;
tabbuf2->blk=tempi->location.big;
FillBigEndianU2(&tabbuf2->parent_entry_num,1);
itabbuf=tabbuf+sizeof(ISOPathTableEntry);
itabbuf2=tabbuf2+sizeof(ISOPathTableEntry);
first_free=2;
for (i=1;i<=max_depth;i++)
CDFillPathTable(rootdir,&itabbuf,&itabbuf2,
1,TRUE,&first_free,1,i);
coutln cur_blk,": Path Table 2";
FWBlks(out_file,tabbuf,cur_blk<<2,tabsize<<2);
cur_blk+=tabsize;
coutln cur_blk,": Path Table 3";
FWBlks(out_file,tabbuf2,cur_blk<<2,tabsize2<<2);
cur_blk+=tabsize2;
DelLTDirList(rootdir); //TODO: Free user_data
FillU4Palindrome(&iso->volume_space_size,cur_blk);
FillU4Palindrome(&iso2->volume_space_size,cur_blk);
FWBlks(out_file,iso,16<<2,4);
iso3->type=ISOT_TERMINATOR;
StrCpy(iso3->id,"CD001");
iso3->version=1;
if (bootfile_buf) {
FWBlks(out_file,iso1,17<<2,4);
FWBlks(out_file,iso2,18<<2,4);
FWBlks(out_file,iso3,19<<2,4);
} else {
FWBlks(out_file,iso2,17<<2,4);
FWBlks(out_file,iso3,18<<2,4);
}
} else
cur_blk=0;
FClose(out_file);
Free(tabbuf);
Free(tabbuf2);
Free(et);
Free(bootfile_buf);
Free(iso);
Free(iso1);
Free(iso2);
Free(iso3);
Free(filename2);
return cur_blk;
}
public void SetDriveTextAttr(I1 drive=0,U1 attr)
{
LTPartition *p;
try {
p=DriveToPartition(drive);
p->text_attr=attr;
} catch {
Fs->catch_except=TRUE;
}
}
public void PrintFDriveTextAttr(I1 drive=0)
{
LTPartition *p=DriveToPartition(drive);
U1 fg=p->text_attr&0xF,bg=p->text_attr>>4;
if (fg!=bg)
PrintF("$$FG,%d$$$$BG,%d$$",fg,bg);
}
U8 SizeFlattenLTDirTree(LTDirEntry *tempm)
{
U8 result=0;
while (tempm) {
result+=sizeof(LTDirEntry)-offset(LTDirEntry.start)+1;
if (tempm->attr & LT_ATTR_DIR)
result+=SizeFlattenLTDirTree(tempm->sub);
tempm=tempm->next;
}
return result+1;
}
U8 FillFlattenLTDirTree(LTDirEntry *tempm,U1 *dst)
{
U8 result=0,i;
while (tempm) {
*dst++=1;
result++;
i=sizeof(LTDirEntry)-offset(LTDirEntry.start);
MemCpy(dst,&tempm->start,i);
dst+=i;
result+=i;
if (tempm->attr & LT_ATTR_DIR) {
i=FillFlattenLTDirTree(tempm->sub,dst);
dst+=i;
result+=i;
}
tempm=tempm->next;
}
*dst=0;
return result+1;
}
public U1 *FlattenLTDirTree(LTDirEntry *tempm,U8 *size=NULL)
{
U8 i=SizeFlattenLTDirTree(tempm);
U1 *buf=MAlloc(i);
FillFlattenLTDirTree(tempm,buf);
if (*size) *size=i;
return buf;
}
U1 *DoUnflattenLTDirTree(U1 *src,LTDirEntry **tempm)
{
U8 i;
LTDirEntry *tempm1;
if (*src++) {
tempm1=MAllocZ(sizeof(LTDirEntry));
*tempm=tempm1;
i=sizeof(LTDirEntry)-offset(LTDirEntry.start);
MemCpy(&tempm1->start,src,i);
src+=i;
if (tempm1->attr & LT_ATTR_DIR)
src=DoUnflattenLTDirTree(src,&tempm1->sub);
src=DoUnflattenLTDirTree(src,&tempm1->next);
} else
*tempm=NULL;
return src;
}
public LTDirEntry *UnflattenLTDirTree(U1 *src)
{
LTDirEntry *tempm=NULL;
DoUnflattenLTDirTree(src,&tempm);
return tempm;
}