LTCD_060719.ISO
This commit is contained in:
commit
f86e69648b
156 files changed
+49537
No files matched your search
@@ -0,0 +1,821 @@
|
||||
|
||||
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;
|
||||
}
|
||||
| ||||