Finished reformatting files in Kernel BlkDev subdirectory.

Reformatted DiskATA.CC, DiskATAId.CC, DiskAddDev.CC, DiskBlk.CC, DiskBlkDev.CC, DiskCDDVD.CC, DiskCFile.CC, DiskCache.CC, DiskClus.CC, DiskCopy.CC, DiskDirA.CC, DiskDirB.CC, DiskDirContext.CC, DiskDrive.CC, DiskFile.CC, DiskFind.CC, DiskFormat.CC, DiskStrA.CC, DiskStrB.CC, FileSysFAT.CC, FileSysRedSea.CC.
Files are not being refactored currently, progress log filename is misnomer, so renamed FilesRefactored.DD to FilesReformatted.DD.
This commit is contained in:
TomAwezome 2020-09-14 15:27:49 -04:00
parent d9ac154e76
commit ec3aa83b55
23 changed files with 2639 additions and 2043 deletions

View file

@ -121,4 +121,19 @@ StartOS.CC
DiskBlkDev.CC
DiskCDDVD.CC
DiskCFile.CC
DiskCache.CC
DiskClus.CC
DiskCopy.CC
DiskDirA.CC
DiskDirB.CC
DiskDirContext.CC
DiskDrive.CC
DiskFile.CC
DiskFind.CC
DiskFormat.CC
DiskStrA.CC
DiskStrB.CC
FileSysFAT.CC
FileSysRedSea.CC
MakeBlkDev.CC
$FG,7$-Tom$FG,0$

View file

@ -38,6 +38,7 @@ U0 ATABlkSel(CBlkDev *bd, I64 blk, I64 count)
Bool ATAWaitNotBUSY(CBlkDev *bd, F64 timeout)
{
I64 i;
do
{
for (i = 0; i < 3; i++)
@ -46,12 +47,14 @@ Bool ATAWaitNotBUSY(CBlkDev *bd, F64 timeout)
Yield;
}
while (!(0 < timeout < tS));
return FALSE;
}
Bool ATAWaitDRQ(CBlkDev *bd, F64 timeout)
{
I64 i;
do
{
for (i = 0; i < 3; i++)
@ -60,6 +63,7 @@ Bool ATAWaitDRQ(CBlkDev *bd, F64 timeout)
Yield;
}
while (!(0 < timeout < tS));
return FALSE;
}
@ -86,6 +90,7 @@ U0 ATACmd(CBlkDev *bd, U8 cmd)
Bool ATAGetRes(CBlkDev *bd, F64 timeout, U8 *buf, I64 count, I64 _avail, Bool one_read)
{
I64 avail, overflow;
bd->flags &= ~BDF_LAST_WAS_WRITE;
MemSet(buf, 0, count);
while (count > 0)
@ -132,6 +137,7 @@ Bool ATAGetRes(CBlkDev *bd, F64 timeout, U8 *buf, I64 count, I64 _avail, Bool on
Bool ATAPIWritePacketWord(CBlkDev *bd, F64 timeout, ...)
{
I64 i;
for (i = 0; i < argc; i++)
{
if (!ATAWaitDRQ(bd, timeout))
@ -140,6 +146,7 @@ Bool ATAPIWritePacketWord(CBlkDev *bd, F64 timeout, ...)
OutU16(bd->base0 + ATAR0_DATA, EndianU16(argv[i]));
bd->last_time = tS;
}
return TRUE;
}
@ -176,6 +183,7 @@ Bool ATAPISeek(CBlkDev *bd, I64 native_blk)
Bool ATAPIStartStop(CBlkDev *bd, F64 timeout, Bool start)
{
I64 i;
if (start)
i = 0x100;
else
@ -195,8 +203,8 @@ Bool ATAPIStartStop(CBlkDev *bd, F64 timeout, Bool start)
I64 ATAGetDevId(CBlkDev *bd, F64 timeout, Bool keep_id_record)
{
I64 res = BDT_NULL;
U16 *id_record = NULL;
I64 res = BDT_NULL;
U16 *id_record = NULL;
if (bd->type != BDT_ATAPI && bd->base1)
OutU8(bd->base1 + ATAR1_CTRL, 0x8);
@ -227,13 +235,15 @@ I64 ATAGetDevId(CBlkDev *bd, F64 timeout, Bool keep_id_record)
Free(bd->dev_id_record);
bd->dev_id_record = id_record;
}
return res;
}
I64 ATAReadNativeMax(CBlkDev *bd, F64 timeout)
{//Returns zero on error
I64 res = 0;
I64 res = 0;
Bool okay = TRUE;
if (bd->type == BDT_ATAPI)
{
if (bd->flags & BDF_EXT_SIZE)
@ -310,7 +320,8 @@ I64 ATAPIReadCapacity(CBlkDev *bd, I64 *_blk_size=NULL)
{//Supposedly this can return a res +/- 75 sects.
//Error might just be for music.
Bool unlock = BlkDevLock(bd);
U32 buf[2];
U32 buf[2];
if (ATAWaitNotBUSY(bd, 0))
{
if (bd->flags & BDF_EXT_SIZE)
@ -339,8 +350,9 @@ I64 ATAPIReadCapacity(CBlkDev *bd, I64 *_blk_size=NULL)
CATAPITrack *ATAPIReadTrackInfo(CBlkDev *bd, I64 blk)
{
CATAPITrack *res = CAlloc(sizeof(CATAPITrack));
Bool unlock = BlkDevLock(bd);
CATAPITrack *res = CAlloc(sizeof(CATAPITrack));
Bool unlock = BlkDevLock(bd);
if (ATAWaitNotBUSY(bd, 0))
{
if (bd->flags & BDF_EXT_SIZE)
@ -411,6 +423,7 @@ Bool ATAInit(CBlkDev *bd)
}
if (unlock)
BlkDevUnlock(bd);
return okay;
}
@ -427,13 +440,14 @@ Bool ATAPIWaitReady(CBlkDev *bd, F64 timeout)
Yield;
}
while (!(0 < timeout < tS));
return FALSE;
}
U0 ATAReadBlks(CBlkDev *bd, U8 *buf, I64 blk, I64 count)
{
I64 retries = 3;
Bool unlock = BlkDevLock(bd);
I64 retries = 3;
Bool unlock = BlkDevLock(bd);
retry:
ATABlkSel(bd, blk, count);
@ -462,6 +476,7 @@ U0 ATAReadBlks(CBlkDev *bd, U8 *buf, I64 blk, I64 count)
I64 ATAProbe(I64 base0, I64 base1, I64 unit)
{
CBlkDev bd;
MemSet(&bd, 0, sizeof(CBlkDev));
bd.type = BDT_ATAPI;
bd.base0 = base0;
@ -475,6 +490,7 @@ I64 ATAProbe(I64 base0, I64 base1, I64 unit)
Bool ATAPIReadBlks2(CBlkDev *bd, F64 timeout, U8 *buf, I64 native_blk, I64 count, Bool lock)
{
Bool res = FALSE, unlock;
if (count <= 0)
return FALSE;
if (lock)
@ -506,9 +522,10 @@ Bool ATAPIReadBlks2(CBlkDev *bd, F64 timeout, U8 *buf, I64 native_blk, I64 count
U0 ATAPIReadBlks(CBlkDev *bd, U8 *buf, I64 blk, I64 count)
{
CDrive *drive = Letter2Drive(bd->first_drive_let);
I64 retry,spc = bd->blk_size >> BLK_SIZE_BITS, n, blk2, l2 = bd->max_reads << 1 + spc << 1;
U8 *dvd_buf = MAlloc(l2 << BLK_SIZE_BITS);
CDrive *drive = Letter2Drive(bd->first_drive_let);
I64 retry, spc = bd->blk_size >> BLK_SIZE_BITS, n, blk2, l2 = bd->max_reads << 1 + spc << 1;
U8 *dvd_buf = MAlloc(l2 << BLK_SIZE_BITS);
if (count > 0)
{
if (blk <= bd->max_reads)
@ -538,8 +555,9 @@ U0 ATAPIReadBlks(CBlkDev *bd, U8 *buf, I64 blk, I64 count)
Bool ATARBlks(CDrive *drive, U8 *buf, I64 blk, I64 count)
{
I64 n;
CBlkDev *bd = drive->bd;
I64 n;
CBlkDev *bd = drive->bd;
while (count > 0)
{
n = count;
@ -561,9 +579,10 @@ Bool ATARBlks(CDrive *drive, U8 *buf, I64 blk, I64 count)
U0 ATAWriteBlks(CBlkDev *bd, U8 *buf, I64 blk, I64 count)
{//For low level disk access.
//Use BlkWrite() instead.
I64 i, U32s_avail, sects_avail, retries = 3;
F64 timeout;
I64 i, U32s_avail, sects_avail, retries = 3;
F64 timeout;
Bool unlock = BlkDevLock(bd);
retry:
ATABlkSel(bd, blk, count);
if (bd->flags & BDF_EXT_SIZE)
@ -610,6 +629,7 @@ retry:
Bool ATAPISync(CBlkDev *bd)
{
Bool okay = TRUE;
if (!ATAWaitNotBUSY(bd, 0))
okay = FALSE;
else
@ -627,6 +647,7 @@ Bool ATAPISync(CBlkDev *bd)
if (!ATAWaitNotBUSY(bd, 0))
okay = FALSE;
}
return okay;
}
@ -650,6 +671,7 @@ U0 ATAPIWriteBlks(CBlkDev *bd, U8 *buf, I64 native_blk, I64 count)
{
I64 U32s_avail;
U8 *buf2;
ATAWaitNotBUSY(bd, 0);
ATAPISeek(bd, native_blk);
@ -699,10 +721,12 @@ U0 ATAPIWriteBlks(CBlkDev *bd, U8 *buf, I64 native_blk, I64 count)
Bool ATAWBlks(CDrive *drive, U8 *buf, I64 blk, I64 count)
{
I64 n, spc;
CBlkDev *bd = drive->bd;
Bool unlock;
I64 n, spc;
CBlkDev *bd = drive->bd;
Bool unlock;
spc = bd->blk_size >> BLK_SIZE_BITS;
if (bd->type == BDT_ATAPI)
{
unlock = BlkDevLock(bd);
@ -731,5 +755,6 @@ Bool ATAWBlks(CDrive *drive, U8 *buf, I64 blk, I64 count)
if (unlock)
BlkDevUnlock(bd);
}
return TRUE;
}

View file

@ -1,8 +1,9 @@
Bool BootDVDProbe(CBlkDev *bd)
{
U8 *img = CAlloc(DVD_BLK_SIZE);
I64 i;
Bool res = FALSE;
U8 *img = CAlloc(DVD_BLK_SIZE);
I64 i;
Bool res = FALSE;
"Port: %04X,%04X Unit: %02X ", bd->base0, bd->base1, bd->unit;
if (ATAProbe(bd->base0, bd->base1, bd->unit) == BDT_ATAPI)
{
@ -29,6 +30,7 @@ Bool BootDVDProbe(CBlkDev *bd)
}
" Nope\n";
Free(img);
return res;
}
@ -104,10 +106,11 @@ Bool BootDVDProbeAll(CBlkDev *bd)
U0 ATARepEntry(I64 base0, I64 base1, I64 unit, U8 *message, CATARep **_head, I64 *num_hints)
{
I64 type;
I64 type;
base0 &= -8;
base1 &= -4;
CATARep *tmpha;
CATARep *tmpha;
if (type = ATAProbe(base0,base1,unit))
{
*num_hints += 1;
@ -148,6 +151,7 @@ Bool ATARepExitAllApplications()
public I64 ATARep(Bool prompt=TRUE, Bool just_ide=FALSE, CATARep **_head=NULL)
{//Report possible ATA devices by probing. Hard disks and CD/DVDs.
I64 d1, d2, i, j, k, count = 0, unlock_flags = 0, num_hints = 0;
#assert BLKDEVS_NUM <= 64
if (_head)
*_head = NULL;
@ -233,9 +237,10 @@ CATARep *ATARepFind(CATARep *haystack_head, I64 needle_num)
CATARep *ATAIDDrives(CATARep *head, CATARep **_ata_drive, CATARep **_atapi_drive)
{//This is for when trying to sort-out main hard drives and CD/DVD drives.
CATARep *res = NULL, *tmpha = head, *ata_drive = NULL, *atapi_drive = NULL;
CBlkDev *bd;
Bool was_silent = Silent, ins_found = FALSE;
CATARep *res = NULL, *tmpha = head, *ata_drive = NULL, *atapi_drive = NULL;
CBlkDev *bd;
Bool was_silent = Silent, ins_found = FALSE;
bd = Letter2BlkDev(':', FALSE);
Silent(was_silent);
while (tmpha)
@ -282,12 +287,14 @@ CATARep *ATAIDDrives(CATARep *head, CATARep **_ata_drive, CATARep **_atapi_drive
*_ata_drive = ata_drive;
if (_atapi_drive)
*_atapi_drive = atapi_drive;
return res;
}
CBlkDev *ATAMount(U8 first_drive_let, I64 type, I64 base0, I64 base1, I64 unit)
{
CBlkDev *res;
if (0 <= first_drive_let - 'A' < DRIVES_NUM && (type == BDT_ATA || type == BDT_ATAPI) && 0 <= unit <= 1)
{
res = BlkDevNextFreeSlot(first_drive_let, type);
@ -297,6 +304,7 @@ CBlkDev *ATAMount(U8 first_drive_let, I64 type, I64 base0, I64 base1, I64 unit)
if (BlkDevAdd(res,, FALSE, FALSE))
return res;
}
return NULL;
}
@ -304,8 +312,9 @@ I64 MountIDEAuto()
{//Try to mount hard drive and CD/DVD, automatically. (Kernel.Config option).
//It uses 'C' and 'T' as first drive letters or whatever you set
//in config when compiling Kernel.BIN.
I64 res = 0;
CATARep *head = NULL, *ata_drive = NULL, *atapi_drive = NULL, *tmpha;
I64 res = 0;
CATARep *head = NULL, *ata_drive = NULL, *atapi_drive = NULL, *tmpha;
ATARep(FALSE, TRUE, &head);
ATAIDDrives(head, &ata_drive, &atapi_drive);
if (ata_drive && ATAMount(blkdev.first_hd_drive_let, BDT_ATA, ata_drive->base0, ata_drive->base1, ata_drive->unit))
@ -329,5 +338,6 @@ I64 MountIDEAuto()
}
LinkedListDel(head);
blkdev.mount_ide_auto_count = res;
return res;
}

View file

@ -1,7 +1,8 @@
U0 BlkDevLockFwdingSet(CBlkDev *bd)
{ //If two blkdevs on same controller, use just one lock
CBlkDev *bd1;
I64 i;
CBlkDev *bd1;
I64 i;
switch (bd->type)
{
case BDT_RAM:
@ -30,10 +31,10 @@ U0 BlkDevLockFwdingSet(CBlkDev *bd)
I64 BlkDevAdd(CBlkDev *bd, I64 prt_num=I64_MIN, Bool whole_drive, Bool make_free)
{//It will mount just one partition of prt_num>=0.
//When repartitioing whole drive, whole_drive=TRUE.
I64 i, j, ext_base, offset, res = 0, num = 0;
CDrive *drive;
CRedSeaBoot br;
CMasterBoot mbr;
I64 i, j, ext_base, offset, res = 0, num = 0;
CDrive *drive;
CRedSeaBoot br;
CMasterBoot mbr;
bd->bd_signature = BD_SIGNATURE_VAL;
if (make_free)
@ -178,12 +179,14 @@ I64 BlkDevAdd(CBlkDev *bd, I64 prt_num=I64_MIN, Bool whole_drive, Bool make_free
BlkDevLockFwdingSet(bd);
else
BlkDevDel(bd);
return res;
}
Bool DriveEnable(U8 drv_let, Bool val)
{//Can unmount or remount, but not mount the first time.
CDrive *drive;
if (drive = Letter2Drive(drv_let,FALSE))
return !LBEqual(&drive->fs_type,FStf_DISABLE,!val);
else
@ -199,14 +202,16 @@ I64 SysI64Get()
Bool GetBaseUnit(CBlkDev *bd)
{
I64 ch;
I64 ch;
Bool probe;
#exe {
if (kernel_config->opts[CONFIG_DONT_PROBE])
StreamPrint("probe = FALSE;");
else
StreamPrint("probe = TRUE;");
};
if (!probe || !BootDVDProbeAll(bd))
{
"\nDon't worry. This is not a product\n"
@ -243,12 +248,14 @@ Bool GetBaseUnit(CBlkDev *bd)
U0 BlkDevsInitAll()
{
CBlkDev *bd;
I64 i;
CBlkDev *bd;
I64 i;
blkdev.blkdevs = CAlloc(sizeof(CBlkDev) * BLKDEVS_NUM);
blkdev.drvs = CAlloc(sizeof(CDrive) * DRIVES_NUM);
for (i = 0; i < DRIVES_NUM; i++)
blkdev.let_to_drive[i] = &blkdev.drvs[i];
#exe {
if (kernel_config->opts[CONFIG_MOUNT_IDE_AUTO])
StreamPrint("MountIDEAuto;");

View file

@ -1,9 +1,10 @@
#define ZERO_BUF_SIZE 2048
U0 BlkWriteZero(CDrive *drive, I64 blk, I64 count)
{//Fill blk count with zeros in Drive.
I64 n;
U8 *z = CAlloc(ZERO_BUF_SIZE << BLK_SIZE_BITS);
I64 n;
U8 *z = CAlloc(ZERO_BUF_SIZE << BLK_SIZE_BITS);
Bool show_progress;
if (count > ZERO_BUF_SIZE && drive->bd->type != BDT_RAM)
{
progress1 = 0;
@ -35,8 +36,9 @@ U0 BlkWriteZero(CDrive *drive, I64 blk, I64 count)
Bool BlkRead(CDrive *drive, U8 *buf, I64 blk, I64 count)
{//Read blk count from Drive to buf.
Bool res = TRUE, unlock;
CBlkDev *bd = drive->bd;
Bool res = TRUE, unlock;
CBlkDev *bd = drive->bd;
if (count <= 0)
return TRUE;
DriveCheck(drive);
@ -74,13 +76,15 @@ Bool BlkRead(CDrive *drive, U8 *buf, I64 blk, I64 count)
catch
if (unlock)
DriveUnlock(drive);
return res;
}
Bool BlkWrite(CDrive *drive, U8 *buf, I64 blk, I64 count)
{//Write blk count from buf to Drive.
Bool res = TRUE, unlock;
CBlkDev *bd = drive->bd;
Bool res = TRUE, unlock;
CBlkDev *bd = drive->bd;
if (count <= 0)
return TRUE;
DriveCheck(drive);
@ -118,5 +122,6 @@ Bool BlkWrite(CDrive *drive, U8 *buf, I64 blk, I64 count)
catch
if (unlock)
DriveUnlock(drive);
return res;
}

View file

@ -1,12 +1,15 @@
Bool BlkDevLock(CBlkDev *bd)
{//Make this task have exclusive access to BlkDev.
BlkDevCheck(bd);
while (bd->lock_fwding)
bd = bd->lock_fwding; //If two blkdevs on same controller, use just one lock
if (!Bt(&bd->locked_flags, BDlf_LOCKED) || bd->owning_task != Fs)
{
while (LBts(&bd->locked_flags, BDlf_LOCKED))
Yield;
bd->owning_task = Fs;
return TRUE;
}
@ -17,8 +20,10 @@ Bool BlkDevLock(CBlkDev *bd)
Bool BlkDevUnlock(CBlkDev *bd, Bool reset=FALSE)
{//Release exclusive lock on access to BlkDev.
BlkDevCheck(bd);
while (bd->lock_fwding)
bd = bd->lock_fwding; //If two blkdevs on same controller, use just one lock
if (Bt(&bd->locked_flags, BDlf_LOCKED) && bd->owning_task == Fs)
{
if (reset)
@ -34,10 +39,11 @@ Bool BlkDevUnlock(CBlkDev *bd, Bool reset=FALSE)
Bool BlkDevInit(CBlkDev *bd)
{
CDirEntry de;
U8 buf[STR_LEN];
CDrive *drive = Letter2Drive(bd->first_drive_let);
Bool res = FALSE;
CDirEntry de;
U8 buf[STR_LEN];
CDrive *drive = Letter2Drive(bd->first_drive_let);
Bool res = FALSE;
if (!LBts(&bd->flags, BDf_INITIALIZED))
{
bd->flags |= BDF_INIT_IN_PROGRESS;
@ -122,13 +128,15 @@ Bool BlkDevInit(CBlkDev *bd)
}
else
res = TRUE;
return res;
}
U0 BlkDevsRelease()
{//When task dies, release all owned BlkDevs.
I64 i;
CBlkDev *bd;
I64 i;
CBlkDev *bd;
for (i = 0; i < BLKDEVS_NUM; i++)
{
bd = &blkdev.blkdevs[i];
@ -139,8 +147,9 @@ U0 BlkDevsRelease()
CBlkDev *BlkDevNextFreeSlot(U8 first_drive_let, I64 type)
{//Locate free slot for new BlkDev, like during $LK,"Mount",A="MN:Mount"$().
I64 i = 0;
CBlkDev *res;
I64 i = 0;
CBlkDev *res;
if (Letter2BlkDevType(first_drive_let) != type)
throw('BlkDev');
do
@ -201,6 +210,7 @@ CBlkDev *BlkDevCheck(CBlkDev *bd, Bool except=TRUE)
CBlkDev *Letter2BlkDev(U8 drv_let=0, Bool except=TRUE)
{//Drive letter to BlkDev ptr.
CDrive *drive;
if (drive = Letter2Drive(drv_let, except))
return BlkDevCheck(drive->bd, except);
else

View file

@ -1,11 +1,11 @@
Bool ISOInit(CDrive *drive, I64 blk)
{
CBlkDev *bd = drive->bd;
I64 spc = bd->blk_size >> BLK_SIZE_BITS, i = blk / spc, drv_offset = 0;
CISOPriDesc *iso = MAlloc(bd->blk_size);
CISODirEntry *de;
Bool unlock, res = FALSE;
U8 buf[8];
CBlkDev *bd = drive->bd;
I64 spc = bd->blk_size >> BLK_SIZE_BITS, i = blk / spc, drv_offset = 0;
CISOPriDesc *iso = MAlloc(bd->blk_size);
CISODirEntry *de;
Bool unlock, res = FALSE;
U8 buf[8];
try
{
@ -71,11 +71,12 @@ di_done:
U0 DVDImageRead(U8 dvd_drive_let, U8 *out_name)
{//Read entire CD/DVD image into ISO file.
CDrive *drive = Letter2Drive(dvd_drive_let);
CBlkDev *bd = drive->bd;
U8 *buf = MAlloc(COPY_BUF_BLKS << BLK_SIZE_BITS), *out_name2 = ExtDefault(out_name, "ISO");
CFile *f = FOpen(out_name2, "w");
I64 n, spc = bd->blk_size >> BLK_SIZE_BITS, blk = 0, count, retry;
CDrive *drive = Letter2Drive(dvd_drive_let);
CBlkDev *bd = drive->bd;
U8 *buf = MAlloc(COPY_BUF_BLKS << BLK_SIZE_BITS), *out_name2 = ExtDefault(out_name, "ISO");
CFile *f = FOpen(out_name2, "w");
I64 n, spc = bd->blk_size >> BLK_SIZE_BITS, blk = 0, count, retry;
BlkDevInit(bd);
if (bd->type != BDT_ATAPI)
throw('BlkDev');
@ -111,17 +112,18 @@ U0 DVDImageRead(U8 dvd_drive_let, U8 *out_name)
class CDualBuf
{
U8 *buf0, *buf1;
I64 in_buf, out_buf, count;
U8 *filename;
CBlkDev *dvd_bd;
U8 *buf0, *buf1;
I64 in_buf, out_buf, count;
U8 *filename;
CBlkDev *dvd_bd;
};
U0 DVDImageWriteTask(CDualBuf *d)
{
U8 *buf;
I64 n, blk = 0, count = d->count;
CFile *f;
U8 *buf;
I64 n, blk = 0, count = d->count;
CFile *f;
if (FileAttr(d->filename) & RS_ATTR_CONTIGUOUS)
f = FOpen(d->filename, "rc");
else
@ -150,13 +152,13 @@ U0 DVDImageWriteTask(CDualBuf *d)
U0 DVDImageWrite(U8 dvd_drive_let, U8 *in_name=NULL, I64 media_type=MT_DVD)
{//Write CD/DVD ISO file to disk.
CDualBuf *d = CAlloc(sizeof(CDualBuf));
U8 *buf, *in_name2, *in_name3;
I64 i, n, spc, blk = 0, count;
CDrive *drive = Letter2Drive(dvd_drive_let);
CBlkDev *bd = drive->bd, *bd2;
CTask *task;
CFile *f;
CDualBuf *d = CAlloc(sizeof(CDualBuf));
U8 *buf, *in_name2, *in_name3;
I64 i, n, spc, blk = 0, count;
CDrive *drive = Letter2Drive(dvd_drive_let);
CBlkDev *bd = drive->bd, *bd2;
CTask *task;
CFile *f;
if (!in_name)
in_name = blkdev.default_iso_filename;

View file

@ -9,10 +9,10 @@ I64 FSize(CFile *f)
CFile *FOpen(U8 *filename, U8 *flags, I64 count=0)
{//Allows flags "r","w","w+". "c" for contiguous.
//(It uses $LK,"StrOcc",A="MN:StrOcc"$() for 'w', 'r', '+', 'c')
CFile *f = CAlloc(sizeof(CFile));
CDirContext *dirc;
U8 *full_name;
Bool contiguous = StrOcc(flags, 'c');
CFile *f = CAlloc(sizeof(CFile));
CDirContext *dirc;
U8 *full_name;
Bool contiguous = StrOcc(flags, 'c');
f->clus = INVALID_CLUS;
f->fblk_num = 0;
@ -75,12 +75,14 @@ CFile *FOpen(U8 *filename, U8 *flags, I64 count=0)
Free(f->clus_buf);
Free(full_name);
Free(f);
return NULL;
}
U0 FClose(CFile *f)
{//Close CFile, updating directory.
CDirContext *dirc;
if (f)
{
if (f->flags & FF_BUF_DIRTY)
@ -111,8 +113,9 @@ U0 FClose(CFile *f)
I64 FSetClus(CFile *f, I64 c, I64 blk, Bool read)
{
CDrive *drive = f->drive;
I64 i;
CDrive *drive = f->drive;
I64 i;
if (f->clus != c)
{
if (f->flags & FF_BUF_DIRTY)
@ -141,13 +144,14 @@ I64 FSetClus(CFile *f, I64 c, I64 blk, Bool read)
c = ClusBlkRead(drive, f->clus_buf, c, i);
}
}
return c;
}
Bool FBlkRead(CFile *f, U8 *buf, I64 blk=FFB_NEXT_BLK, I64 count=1)
{//Read [nth,n+count) blks of file.
CDrive *drive = f->drive;
I64 spc = drive->spc, i, j, c = f->de.clus;
CDrive *drive = f->drive;
I64 spc = drive->spc, i, j, c = f->de.clus;
if (!f || !drive)
return FALSE;
@ -203,13 +207,14 @@ Bool FBlkRead(CFile *f, U8 *buf, I64 blk=FFB_NEXT_BLK, I64 count=1)
}
}
f->fblk_num = blk;
return TRUE;
}
Bool FBlkWrite(CFile *f, U8 *buf, I64 blk=FFB_NEXT_BLK, I64 count=1)
{//Write [nth,n+count) blks of file.
CDrive *drive = f->drive;
I64 spc = drive->spc, i, j, c = f->de.clus, c1;
CDrive *drive = f->drive;
I64 spc = drive->spc, i, j, c = f->de.clus, c1;
if (!f || !drive)
return FALSE;
@ -305,5 +310,6 @@ Bool FBlkWrite(CFile *f, U8 *buf, I64 blk=FFB_NEXT_BLK, I64 count=1)
f->de.size = blk << BLK_SIZE_BITS;
}
f->fblk_num = blk;
return TRUE;
}

View file

@ -1,145 +1,168 @@
U0 DiskCacheInit(I64 size_in_U8s)
{
CCacheBlk *tmpc;
I64 i,count;
CCacheBlk *tmpc;
I64 i, count;
while (LBts(&sys_semas[SEMA_DISK_CACHE],0))
while (LBts(&sys_semas[SEMA_DISK_CACHE], 0))
Yield;
Free(blkdev.cache_ctrl);
Free(blkdev.cache_base);
Free(blkdev.cache_hash_table);
if (size_in_U8s<0x2000) {
blkdev.cache_ctrl=NULL;
blkdev.cache_base=NULL;
blkdev.cache_hash_table=NULL;
} else {
blkdev.cache_ctrl=ZCAlloc(offset(CCacheBlk.body));
blkdev.cache_base=ZMAlloc(size_in_U8s);
if (size_in_U8s < 0x2000)
{
blkdev.cache_ctrl = NULL;
blkdev.cache_base = NULL;
blkdev.cache_hash_table = NULL;
}
else
{
blkdev.cache_ctrl = ZCAlloc(offset(CCacheBlk.body));
blkdev.cache_base = ZMAlloc(size_in_U8s);
QueueInit(blkdev.cache_ctrl);
count=MSize(blkdev.cache_base)/sizeof(CCacheBlk);
blkdev.cache_size=count*BLK_SIZE;
for (i=0;i<count;i++) {
tmpc=blkdev.cache_base+i;
QueueInsert(tmpc,blkdev.cache_ctrl->last_lru);
tmpc->next_hash=tmpc->last_hash=tmpc;
tmpc->drive=NULL;
tmpc->blk=0;
count = MSize(blkdev.cache_base) / sizeof(CCacheBlk);
blkdev.cache_size = count * BLK_SIZE;
for (i = 0; i < count; i++)
{
tmpc = blkdev.cache_base+i;
QueueInsert(tmpc, blkdev.cache_ctrl->last_lru);
tmpc->next_hash = tmpc->last_hash = tmpc;
tmpc->drive = NULL;
tmpc->blk = 0;
}
blkdev.cache_hash_table=ZMAlloc(DISK_CACHE_HASH_SIZE*sizeof(U8 *)*2);
for (i=0;i<DISK_CACHE_HASH_SIZE;i++) {
tmpc=blkdev.cache_hash_table(U8 *)+i*sizeof(U8 *)*2
-offset(CCacheBlk.next_hash);
tmpc->next_hash=tmpc->last_hash=tmpc;
blkdev.cache_hash_table = ZMAlloc(DISK_CACHE_HASH_SIZE * sizeof(U8 *) * 2);
for (i = 0; i < DISK_CACHE_HASH_SIZE; i++)
{
tmpc = blkdev.cache_hash_table(U8 *) + i * sizeof(U8 *) * 2 - offset(CCacheBlk.next_hash);
tmpc->next_hash = tmpc->last_hash = tmpc;
}
}
LBtr(&sys_semas[SEMA_DISK_CACHE],0);
LBtr(&sys_semas[SEMA_DISK_CACHE], 0);
}
I64 DiskCacheHash(I64 blk)
{
I64 i=blk & (DISK_CACHE_HASH_SIZE-1);
return blkdev.cache_hash_table(U8 *)+i<<4-offset(CCacheBlk.next_hash);
I64 i = blk & (DISK_CACHE_HASH_SIZE - 1);
return blkdev.cache_hash_table(U8 *) + i << 4 - offset(CCacheBlk.next_hash);
}
U0 DiskCacheQueueRemove(CCacheBlk *tmpc)
{
QueueRemove(tmpc);
tmpc->next_hash->last_hash=tmpc->last_hash;
tmpc->last_hash->next_hash=tmpc->next_hash;
tmpc->next_hash->last_hash = tmpc->last_hash;
tmpc->last_hash->next_hash = tmpc->next_hash;
}
U0 DiskCacheQueueIns(CCacheBlk *tmpc)
{
CCacheBlk *tmp_n,*tmp_l;
QueueInsert(tmpc,blkdev.cache_ctrl->last_lru);
tmp_l=DiskCacheHash(tmpc->blk);
tmp_n=tmp_l->next_hash;
tmpc->last_hash=tmp_l;
tmpc->next_hash=tmp_n;
tmp_l->next_hash=tmp_n->last_hash=tmpc;
CCacheBlk *tmp_n, *tmp_l;
QueueInsert(tmpc, blkdev.cache_ctrl->last_lru);
tmp_l = DiskCacheHash(tmpc->blk);
tmp_n = tmp_l->next_hash;
tmpc->last_hash = tmp_l;
tmpc->next_hash = tmp_n;
tmp_l->next_hash = tmp_n->last_hash = tmpc;
}
CCacheBlk *DiskCacheFind(CDrive *drive,I64 blk)
CCacheBlk *DiskCacheFind(CDrive *drive, I64 blk)
{
CCacheBlk *tmpc,*tmpc1=DiskCacheHash(blk);
tmpc=tmpc1->next_hash;
while (tmpc!=tmpc1) {
if (tmpc->drive==drive && tmpc->blk==blk)
CCacheBlk *tmpc, *tmpc1 = DiskCacheHash(blk);
tmpc = tmpc1->next_hash;
while (tmpc != tmpc1)
{
if (tmpc->drive == drive && tmpc->blk == blk)
return tmpc;
tmpc=tmpc->next_hash;
tmpc = tmpc->next_hash;
}
return NULL;
}
U0 DiskCacheAdd(CDrive *drive,U8 *buf, I64 blk, I64 count)
U0 DiskCacheAdd(CDrive *drive, U8 *buf, I64 blk, I64 count)
{
CCacheBlk *tmpc;
if (blkdev.cache_base) {
while (LBts(&sys_semas[SEMA_DISK_CACHE],0))
if (blkdev.cache_base)
{
while (LBts(&sys_semas[SEMA_DISK_CACHE], 0))
Yield;
while (count-->0) {
if (!(tmpc=DiskCacheFind(drive,blk)))
tmpc=blkdev.cache_ctrl->next_lru;
while (count-- > 0)
{
if (!(tmpc = DiskCacheFind(drive, blk)))
tmpc = blkdev.cache_ctrl->next_lru;
DiskCacheQueueRemove(tmpc);
MemCopy(&tmpc->body,buf,BLK_SIZE);
tmpc->drive=drive;
tmpc->blk=blk;
MemCopy(&tmpc->body, buf, BLK_SIZE);
tmpc->drive = drive;
tmpc->blk = blk;
DiskCacheQueueIns(tmpc);
blk++;
buf+=BLK_SIZE;
buf += BLK_SIZE;
}
LBtr(&sys_semas[SEMA_DISK_CACHE],0);
LBtr(&sys_semas[SEMA_DISK_CACHE], 0);
}
}
U0 DiskCacheInvalidate2(CDrive *drive)
{
CCacheBlk *tmpc,*tmpc1;
if (blkdev.cache_base) {
while (LBts(&sys_semas[SEMA_DISK_CACHE],0))
CCacheBlk *tmpc, *tmpc1;
if (blkdev.cache_base)
{
while (LBts(&sys_semas[SEMA_DISK_CACHE], 0))
Yield;
tmpc=blkdev.cache_ctrl->last_lru;
while (tmpc!=blkdev.cache_ctrl) {
tmpc1=tmpc->last_lru;
if (tmpc->drive==drive) {
tmpc = blkdev.cache_ctrl->last_lru;
while (tmpc != blkdev.cache_ctrl)
{
tmpc1 = tmpc->last_lru;
if (tmpc->drive == drive)
{
DiskCacheQueueRemove(tmpc);
tmpc->drive=NULL;
tmpc->blk=0;
tmpc->next_hash=tmpc->last_hash=tmpc;
QueueInsert(tmpc,blkdev.cache_ctrl->last_lru);
tmpc->drive = NULL;
tmpc->blk = 0;
tmpc->next_hash = tmpc->last_hash = tmpc;
QueueInsert(tmpc, blkdev.cache_ctrl->last_lru);
}
tmpc=tmpc1;
tmpc = tmpc1;
}
LBtr(&sys_semas[SEMA_DISK_CACHE],0);
LBtr(&sys_semas[SEMA_DISK_CACHE], 0);
}
}
U0 RCache(CDrive *drive,U8 **_buf, I64 *_blk, I64 *_count)
U0 RCache(CDrive *drive, U8 **_buf, I64 *_blk, I64 *_count)
{
CCacheBlk *tmpc;
if (blkdev.cache_base) {
while (LBts(&sys_semas[SEMA_DISK_CACHE],0))
if (blkdev.cache_base)
{
while (LBts(&sys_semas[SEMA_DISK_CACHE], 0))
Yield;
//fetch leading blks from cache
while (*_count>0) {
if (tmpc=DiskCacheFind(drive,*_blk)) {
MemCopy(*_buf,&tmpc->body,BLK_SIZE);
*_count-=1;
*_buf+=BLK_SIZE;
*_blk+=1;
} else
while (*_count > 0)
{
if (tmpc = DiskCacheFind(drive, *_blk))
{
MemCopy(*_buf, &tmpc->body, BLK_SIZE);
*_count -= 1;
*_buf += BLK_SIZE;
*_blk += 1;
}
else
break;
}
//fetch trailing blks from cache
while (*_count>0) {
if (tmpc=DiskCacheFind(drive,*_blk+*_count-1)) {
MemCopy(*_buf+(*_count-1)<<BLK_SIZE_BITS,&tmpc->body,BLK_SIZE);
*_count-=1;
} else
while (*_count > 0)
{
if (tmpc = DiskCacheFind(drive, *_blk + *_count - 1))
{
MemCopy(*_buf + (*_count - 1) << BLK_SIZE_BITS, &tmpc->body, BLK_SIZE);
*_count -= 1;
}
else
break;
}
LBtr(&sys_semas[SEMA_DISK_CACHE],0);
LBtr(&sys_semas[SEMA_DISK_CACHE], 0);
}
}

View file

@ -1,68 +1,79 @@
I64 ClusNumNext(CDrive *drive,I64 c,I64 count=1)
I64 ClusNumNext(CDrive *drive, I64 c, I64 count=1)
{//Return next count'th clus in chain.
Bool unlock;
DriveCheck(drive);
if (count<=0) return c;
try {
unlock=DriveLock(drive);
switch (drive->fs_type) {
if (count <= 0) return c;
try
{
unlock = DriveLock(drive);
switch (drive->fs_type)
{
case FSt_REDSEA:
c+=count;
c += count;
break;
case FSt_FAT32:
while (count-->0 && 0<c<0x0FFFFFF8) {
DriveFATBlkSet(drive,c);
c=drive->cur_fat_blk[c & (BLK_SIZE/4-1)];
while (count-- > 0 && 0 < c < 0x0FFFFFF8)
{
DriveFATBlkSet(drive, c);
c = drive->cur_fat_blk[c & (BLK_SIZE / 4 - 1)];
}
if (!(0<c<0x0FFFFFF8))
c=INVALID_CLUS;
if (!(0 < c < 0x0FFFFFF8))
c = INVALID_CLUS;
break;
default:
throw('Drive');
}
if (unlock)
DriveUnlock(drive);
} catch
}
catch
if (unlock)
DriveUnlock(drive);
return c;
}
I64 Clus2Blk(CDrive *drive,I64 c)
I64 Clus2Blk(CDrive *drive, I64 c)
{//Drive clus num to blk num.
DriveCheck(drive);
switch (drive->fs_type) {
switch (drive->fs_type)
{
case FSt_REDSEA:
return c;
case FSt_FAT32:
return drive->data_area+c*drive->spc;
return drive->data_area + c * drive->spc;
default:
throw('Drive');
}
}
I64 ClusBlkRead(CDrive *drive,U8 *buf,I64 c,I64 blks)
I64 ClusBlkRead(CDrive *drive, U8 *buf, I64 c, I64 blks)
{//Accepts blk count, so padding on last clus is not read.
I64 i;
I64 i;
Bool unlock;
DriveCheck(drive);
if (blks<=0) return c;
try {
unlock=DriveLock(drive);
switch (drive->fs_type) {
if (blks <= 0) return c;
try
{
unlock = DriveLock(drive);
switch (drive->fs_type)
{
case FSt_REDSEA:
BlkRead(drive,buf,c,blks);
c+=blks;
BlkRead(drive, buf, c, blks);
c += blks;
break;
case FSt_FAT32:
while (blks && 0<c<0x0FFFFFF8) {
i=blks;
if (i>drive->spc)
i=drive->spc;
BlkRead(drive,buf,drive->data_area+c*drive->spc,i);
buf+=i<<BLK_SIZE_BITS;
c=ClusNumNext(drive,c,1);
blks-=i;
while (blks && 0 < c < 0x0FFFFFF8)
{
i = blks;
if (i > drive->spc)
i = drive->spc;
BlkRead(drive, buf, drive->data_area + c * drive->spc, i);
buf+=i << BLK_SIZE_BITS;
c = ClusNumNext(drive, c, 1);
blks -= i;
}
if (blks)
throw('Drive');
@ -72,41 +83,47 @@ I64 ClusBlkRead(CDrive *drive,U8 *buf,I64 c,I64 blks)
}
if (unlock)
DriveUnlock(drive);
} catch
}
catch
if (unlock)
DriveUnlock(drive);
return c;
}
I64 ClusRead(CDrive *drive,U8 *buf,I64 c,I64 count)
I64 ClusRead(CDrive *drive, U8 *buf, I64 c, I64 count)
{//Read clus count from drv to buf.
return ClusBlkRead(drive,buf,c,count*drive->spc);
return ClusBlkRead(drive, buf, c, count*drive->spc);
}
I64 ClusBlkWrite(CDrive *drive,U8 *buf,I64 c,I64 blks)
I64 ClusBlkWrite(CDrive *drive, U8 *buf, I64 c, I64 blks)
{//Accepts blk count, so padding on last clus is not written.
I64 i;
I64 i;
Bool unlock;
DriveCheck(drive);
if (blks<=0) return c;
try {
unlock=DriveLock(drive);
switch (drive->fs_type) {
if (blks <= 0) return c;
try
{
unlock = DriveLock(drive);
switch (drive->fs_type)
{
case FSt_REDSEA:
BlkWrite(drive,buf,c,blks);
c=0;
BlkWrite(drive, buf, c, blks);
c = 0;
break;
case FSt_FAT32:
while (blks) {
if (!(0<c<0x0FFFFFF8))
while (blks)
{
if (!(0 < c < 0x0FFFFFF8))
throw('Drive');
i=blks;
if (i>drive->spc)
i=drive->spc;
BlkWrite(drive,buf,drive->data_area+c*drive->spc,i);
buf+=i<<BLK_SIZE_BITS;
c=ClusNumNext(drive,c);
blks-=i;
i = blks;
if (i > drive->spc)
i = drive->spc;
BlkWrite(drive, buf, drive->data_area + c * drive->spc, i);
buf += i << BLK_SIZE_BITS;
c = ClusNumNext(drive, c);
blks -= i;
}
break;
default:
@ -114,31 +131,36 @@ I64 ClusBlkWrite(CDrive *drive,U8 *buf,I64 c,I64 blks)
}
if (unlock)
DriveUnlock(drive);
} catch
}
catch
if (unlock)
DriveUnlock(drive);
return c;
}
I64 ClusWrite(CDrive *drive,U8 *buf,I64 c,I64 count)
I64 ClusWrite(CDrive *drive, U8 *buf, I64 c, I64 count)
{//Write clus count from buf to drv.
return ClusBlkWrite(drive,buf,c,count*drive->spc);
return ClusBlkWrite(drive, buf, c, count*drive->spc);
}
I64 ClusAlloc(CDrive *drive,I64 c=0,I64 count=1,Bool contiguous=FALSE)
I64 ClusAlloc(CDrive *drive, I64 c=0, I64 count=1, Bool contiguous=FALSE)
{//Alloc clus count into chain.
//c=0 means first clus in chain
DriveCheck(drive);
if (count<=0) return c;
switch (drive->fs_type) {
if (count <= 0) return c;
switch (drive->fs_type)
{
case FSt_REDSEA:
return RedSeaAllocClus(drive,count);
return RedSeaAllocClus(drive, count);
case FSt_FAT32:
if (contiguous) {
if (contiguous)
{
if (c) throw('File');
return FAT32AllocContiguousClus(drive,count);
} else
return FAT32AllocClus(drive,c,count);
return FAT32AllocContiguousClus(drive, count);
}
else
return FAT32AllocClus(drive, c, count);
default:
throw('Drive');
}

View file

@ -1,103 +1,121 @@
Bool CopySingleZ(U8 *f1,U8 *f2) //Just one file
Bool CopySingleZ(U8 *f1, U8 *f2) //Just one file
{
U8 *file_buf=NULL;
I64 size,attr=0,c;
CDirEntry de;
if (FileFind(f1,&de,FUF_JUST_FILES)) {
U8 *file_buf=NULL;
I64 size, attr=0, c;
CDirEntry de;
if (FileFind(f1, &de, FUF_JUST_FILES))
{
Free(de.full_name);
file_buf=FileRead(f1,&size,&attr);
attr=FileAttr(f2,attr);
if (file_buf) {
"Copying %s to %s\n",f1,f2;
c=FileWrite(f2,file_buf,size,de.datetime,attr);
file_buf = FileRead(f1, &size, &attr);
attr = FileAttr(f2, attr);
if (file_buf)
{
"Copying %s to %s\n", f1, f2;
c = FileWrite(f2, file_buf, size, de.datetime, attr);
Free(file_buf);
return ToBool(c);
} else
PrintErr("File not found: \"%s\".\n",f1);
} else
PrintErr("File not found: \"%s\".\n",f1);
}
else
PrintErr("File not found: \"%s\".\n", f1);
}
else
PrintErr("File not found: \"%s\".\n", f1);
return FALSE;
}
#define COPY_BUF_BLKS 0x80
Bool CopySingle(U8 *f1,U8 *f2) //Just one file
Bool CopySingle(U8 *f1, U8 *f2) //Just one file
{
U8 *absf1=FileNameAbs(f1),*absf2=FileNameAbs(f2),*buf;
I64 count,n,size,attr1=FileAttr(f1),attr2=FileAttr(f2),i,j;
CFile *in_file=NULL,*out_file=NULL;
if (!StrCompare(absf1,absf2)) {//onto self?
U8 *absf1 = FileNameAbs(f1), *absf2 = FileNameAbs(f2), *buf;
I64 count, n, size, attr1 = FileAttr(f1), attr2 = FileAttr(f2), i, j;
CFile *in_file = NULL, *out_file = NULL;
if (!StrCompare(absf1, absf2))
{//onto self?
Free(absf1);
Free(absf2);
return FALSE;
}
Free(absf1);
Free(absf2);
if (attr1!=attr2)
return CopySingleZ(f1,f2);
buf=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS);
if (attr1 != attr2)
return CopySingleZ(f1, f2);
buf = MAlloc(COPY_BUF_BLKS << BLK_SIZE_BITS);
if (attr1 & RS_ATTR_CONTIGUOUS)
in_file=FOpen(f1,"rc");
in_file = FOpen(f1, "rc");
else
in_file=FOpen(f1,"r");
if (in_file) {
size=FSize(in_file);
count=(size+BLK_SIZE-1)>>BLK_SIZE_BITS;
in_file = FOpen(f1, "r");
if (in_file)
{
size = FSize(in_file);
count = (size + BLK_SIZE - 1) >> BLK_SIZE_BITS;
if (attr2 & RS_ATTR_CONTIGUOUS)
out_file=FOpen(f2,"wc",count);
out_file = FOpen(f2, "wc", count);
else
out_file=FOpen(f2,"w",count);
if (out_file) {
"Copying %s to %s\n",f1,f2;
j=size;
while (count>0) {
if (count>COPY_BUF_BLKS) {
n=COPY_BUF_BLKS;
i=n<<BLK_SIZE_BITS;
} else {
n=count;
i=j;
out_file = FOpen(f2, "w", count);
if (out_file)
{
"Copying %s to %s\n", f1, f2;
j = size;
while (count > 0)
{
if (count > COPY_BUF_BLKS)
{
n = COPY_BUF_BLKS;
i = n << BLK_SIZE_BITS;
}
FBlkRead(in_file, buf,FFB_NEXT_BLK,n);
FBlkWrite(out_file,buf,FFB_NEXT_BLK,n);
count-=n;
j-=n<<BLK_SIZE_BITS;
else
{
n = count;
i = j;
}
FBlkRead(in_file, buf, FFB_NEXT_BLK, n);
FBlkWrite(out_file, buf, FFB_NEXT_BLK, n);
count -= n;
j -= n << BLK_SIZE_BITS;
}
out_file->flags|=FF_USE_OLD_DATETIME;
out_file->de.datetime=in_file->de.datetime;
out_file->de.size=size;
out_file->de.attr=FileAttr(f2,in_file->de.attr);
out_file->flags |= FF_USE_OLD_DATETIME;
out_file->de.datetime = in_file->de.datetime;
out_file->de.size = size;
out_file->de.attr = FileAttr(f2, in_file->de.attr);
FClose(out_file);
FClose(in_file);
Free(buf);
return TRUE;
} else
PrintErr("File not found: \"%s\".\n",f2);
}
else
PrintErr("File not found: \"%s\".\n", f2);
FClose(in_file);
} else
PrintErr("File not found: \"%s\".\n",f1);
}
else
PrintErr("File not found: \"%s\".\n", f1);
Free(buf);
return FALSE;
}
I64 Del(U8 *files_find_mask,Bool make_mask=FALSE,
Bool del_dir=FALSE,Bool print_message=TRUE)
I64 Del(U8 *files_find_mask, Bool make_mask=FALSE, Bool del_dir=FALSE, Bool print_message=TRUE)
{//Delete files.
I64 res=0;
CDirContext *dirc;
if (dirc=DirContextNew(files_find_mask,make_mask)) {
switch (dirc->drive->fs_type) {
I64 res = 0;
CDirContext *dirc;
if (dirc = DirContextNew(files_find_mask, make_mask))
{
switch (dirc->drive->fs_type)
{
case FSt_REDSEA:
res=RedSeaFilesDel(dirc->drive,Fs->cur_dir,dirc->mask,
0,del_dir,print_message);
res = RedSeaFilesDel(dirc->drive, Fs->cur_dir, dirc->mask, 0, del_dir, print_message);
break;
case FSt_FAT32:
res=FAT32FilesDel(dirc->drive,Fs->cur_dir,dirc->mask,
0,del_dir,print_message);
res = FAT32FilesDel(dirc->drive, Fs->cur_dir, dirc->mask, 0, del_dir, print_message);
break;
default:
PrintErr("File System Not Supported\n");
}
DirContextDel(dirc);
}
return res;
}

View file

@ -1,10 +1,11 @@
Bool DirNew(CDrive *drive,U8 *cur_dir,CDirEntry *tmpde,Bool free_old_chain=TRUE)
Bool DirNew(CDrive *drive, U8 *cur_dir, CDirEntry *tmpde, Bool free_old_chain=TRUE)
{//Makes a directory entry in the directory from a $LK,"CDirEntry",A="MN:CDirEntry"$ node.
switch (drive->fs_type) {
switch (drive->fs_type)
{
case FSt_REDSEA:
return RedSeaDirNew(drive,cur_dir,tmpde,free_old_chain);
return RedSeaDirNew(drive, cur_dir, tmpde, free_old_chain);
case FSt_FAT32:
return FAT32DirNew(drive,cur_dir,tmpde,free_old_chain);
return FAT32DirNew(drive, cur_dir, tmpde, free_old_chain);
default:
PrintErr("File System Not Supported\n");
return FALSE;
@ -14,7 +15,8 @@ Bool DirNew(CDrive *drive,U8 *cur_dir,CDirEntry *tmpde,Bool free_old_chain=TRUE)
U0 DirEntryDel(CDirEntry *tmpde)
{//Free node returned from $LK,"FilesFind",A="MN:FilesFind"$(). Doesn't Free user_data.
//Does not change the directory on disk.
if (tmpde) {
if (tmpde)
{
Free(tmpde->full_name);
Free(tmpde);
}
@ -23,7 +25,8 @@ U0 DirEntryDel(CDirEntry *tmpde)
U0 DirEntryDel2(CDirEntry *tmpde)
{//Free node returned from $LK,"FilesFind",A="MN:FilesFind"$(). Frees user_data
//Does not change the directory on disk.
if (tmpde) {
if (tmpde)
{
Free(tmpde->full_name);
Free(tmpde->user_data);
Free(tmpde);
@ -34,12 +37,14 @@ U0 DirTreeDel(CDirEntry *tmpde)
{//Free tree returned from $LK,"FilesFind",A="MN:FilesFind"$(). Doesn't Free user_data.
//Does not change the directory on disk.
CDirEntry *tmpde2;
while (tmpde) {
tmpde2=tmpde->next;
while (tmpde)
{
tmpde2 = tmpde->next;
if (tmpde->sub)
DirTreeDel(tmpde->sub);
DirEntryDel(tmpde);
tmpde=tmpde2;
tmpde = tmpde2;
}
}
@ -47,165 +52,195 @@ U0 DirTreeDel2(CDirEntry *tmpde)
{//Free tree returned from $LK,"FilesFind",A="MN:FilesFind"$(). Frees user_data
//Does not change the directory on disk.
CDirEntry *tmpde2;
while (tmpde) {
tmpde2=tmpde->next;
while (tmpde)
{
tmpde2 = tmpde->next;
if (tmpde->sub)
DirTreeDel2(tmpde->sub);
DirEntryDel2(tmpde);
tmpde=tmpde2;
tmpde = tmpde2;
}
}
I64 DirEntryCompareName(CDirEntry *e1,CDirEntry *e2)
I64 DirEntryCompareName(CDirEntry *e1, CDirEntry *e2)
{
U8 buf1[CDIR_FILENAME_LEN],buf2[CDIR_FILENAME_LEN],
buf3[CDIR_FILENAME_LEN],buf4[CDIR_FILENAME_LEN];
I64 d1=0,d2=0;
U8 buf1[CDIR_FILENAME_LEN], buf2[CDIR_FILENAME_LEN], buf3[CDIR_FILENAME_LEN], buf4[CDIR_FILENAME_LEN];
I64 d1 = 0, d2 = 0;
if (e1->attr & RS_ATTR_DIR)
d1=1;
d1 = 1;
if (e2->attr & RS_ATTR_DIR)
d2=1;
if (d1!=d2)
d2 = 1;
if (d1 != d2)
return d2-d1;
else {
StrCopy(buf1,e1->name);
StrCopy(buf2,e2->name);
FileExtRemove(buf1,buf3);
FileExtRemove(buf2,buf4);
if (d1=StrCompare(buf3,buf4))
else
{
StrCopy(buf1, e1->name);
StrCopy(buf2, e2->name);
FileExtRemove(buf1, buf3);
FileExtRemove(buf2, buf4);
if (d1 = StrCompare(buf3, buf4))
return d1;
return StrCompare(buf1,buf2);
return StrCompare(buf1, buf2);
}
}
I64 DirEntryCompareClus(CDirEntry *e1,CDirEntry *e2)
I64 DirEntryCompareClus(CDirEntry *e1, CDirEntry *e2)
{
return e1->clus-e2->clus;
return e1->clus - e2->clus;
}
#define SK_NAME 0
#define SK_NAME 0
#define SK_CLUS 1
U0 DirFilesSort(CDirEntry **_tmpde,I64 key)
U0 DirFilesSort(CDirEntry **_tmpde, I64 key)
{
I64 i,count;
CDirEntry *tmpde=*_tmpde,*tmpde1,**sort_buf;
if (tmpde) {
count=LinkedListCount(tmpde);
if (count>1) {
sort_buf=MAlloc(count*sizeof(U8 *));
i=0;
tmpde1=tmpde;
while (tmpde1) {
sort_buf[i++]=tmpde1;
tmpde1=tmpde1->next;
I64 i, count;
CDirEntry *tmpde = *_tmpde, *tmpde1, **sort_buf;
if (tmpde)
{
count = LinkedListCount(tmpde);
if (count > 1)
{
sort_buf = MAlloc(count * sizeof(U8 *));
i = 0;
tmpde1 = tmpde;
while (tmpde1)
{
sort_buf[i++] = tmpde1;
tmpde1 = tmpde1->next;
}
switch [key] {
switch [key]
{
case SK_NAME:
QuickSortI64(sort_buf,count,&DirEntryCompareName);
QuickSortI64(sort_buf, count, &DirEntryCompareName);
break;
case SK_CLUS:
QuickSortI64(sort_buf,count,&DirEntryCompareClus);
QuickSortI64(sort_buf, count, &DirEntryCompareClus);
break;
}
tmpde=sort_buf[0];
*_tmpde=tmpde;
for (i=0;i<count-1;i++) {
tmpde1=sort_buf[i];
tmpde1->next=sort_buf[i+1];
tmpde = sort_buf[0];
*_tmpde = tmpde;
for (i = 0; i < count - 1; i++)
{
tmpde1 = sort_buf[i];
tmpde1->next = sort_buf[i + 1];
}
tmpde1=sort_buf[i];
tmpde1->next=NULL;
tmpde1 = sort_buf[i];
tmpde1->next = NULL;
Free(sort_buf);
tmpde1=tmpde;
while (tmpde1) {
tmpde1 = tmpde;
while (tmpde1)
{
if (tmpde1->sub)
DirFilesSort(&tmpde1->sub,key);
tmpde1=tmpde1->next;
DirFilesSort(&tmpde1->sub, key);
tmpde1 = tmpde1->next;
}
} else
}
else
if (tmpde->sub)
DirFilesSort(&tmpde->sub,key);
DirFilesSort(&tmpde->sub, key);
}
}
CDirEntry *DirFilesFlatten(CDirEntry *tmpde,CDirEntry **_res,I64 fuf_flags)
CDirEntry *DirFilesFlatten(CDirEntry *tmpde, CDirEntry **_res, I64 fuf_flags)
{//Returns last node
CDirEntry *tmpde1;
Bool del;
CDirEntry *tmpde1;
Bool del;
if (tmpde)
while (TRUE) {
tmpde1=tmpde->next;
if (!(tmpde->attr&RS_ATTR_DIR)||!(fuf_flags&FUF_JUST_FILES)) {
_res=*_res=tmpde;
del=FALSE;
} else
del=TRUE;
if (tmpde->sub) {
_res=DirFilesFlatten(tmpde->sub,_res,fuf_flags);
tmpde->sub=NULL;
while (TRUE)
{
tmpde1 = tmpde->next;
if (!(tmpde->attr & RS_ATTR_DIR) || !(fuf_flags & FUF_JUST_FILES))
{
_res = *_res = tmpde;
del = FALSE;
}
else
del = TRUE;
if (tmpde->sub)
{
_res = DirFilesFlatten(tmpde->sub, _res, fuf_flags);
tmpde->sub = NULL;
}
if (del)
DirEntryDel(tmpde);
if (tmpde1)
tmpde=tmpde1;
tmpde = tmpde1;
else
break;
}
*_res=NULL;
*_res = NULL;
return _res;
}
U0 PutFileLink(U8 *filename,U8 *full_name=NULL,I64 line=0,Bool plain_text=FALSE)
U0 PutFileLink(U8 *filename, U8 *full_name=NULL, I64 line=0, Bool plain_text=FALSE)
{//Put $LK,"DolDoc",A="FI:::/Doc/DolDocOverview.DD"$ file,line link to StdOut, $LK,"DocPut",A="MN:DocPut"$.
U8 *st;
if (!filename) return;
if (IsRaw) {
if (!filename)
return;
if (IsRaw)
{
if (line)
"%s,%04d",filename,line;
"%s,%04d", filename, line;
else
"%s",filename;
} else {
"%s", filename;
}
else
{
//LK_DOC,LK_DOC_ANCHOR,LK_DOC_FIND,LK_DOC_LINE
if (filename[0]=='A'&&filename[2]==':') {
if (filename[0] == 'A'&&filename[2] == ':')
{
if (line) //See $LK,"SpriteEdText",A="MN:SpriteEdText"$()
"$$LK,\"%s,%04d\",A=\"AL:%s,%d\"$$",filename+3,line,filename+3,line;
"$$LK,\"%s,%04d\",A=\"AL:%s,%d\"$$", filename + 3, line, filename + 3, line;
else
"$$LK,\"%s\",A=\"AI:%s\"$$",filename+3,filename+3;
} else {
"$$LK,\"%s\",A=\"AI:%s\"$$", filename + 3, filename + 3;
}
else
{
if (!full_name)
full_name=st=FileNameAbs(filename);
full_name = st = FileNameAbs(filename);
else
st=NULL;
if (plain_text) {
st = NULL;
if (plain_text)
{
if (line)
"$$LK,\"%s,%04d\",A=\"PL:%s,%d\"$$",filename,line,full_name,line;
"$$LK,\"%s,%04d\",A=\"PL:%s,%d\"$$", filename, line, full_name, line;
else
"$$LK,\"%s\",A=\"PI:%s\"$$",filename,full_name;
} else {
"$$LK,\"%s\",A=\"PI:%s\"$$", filename, full_name;
}
else
{
if (line)
"$$LK,\"%s,%04d\",A=\"FL:%s,%d\"$$",filename,line,full_name,line;
"$$LK,\"%s,%04d\",A=\"FL:%s,%d\"$$", filename, line, full_name, line;
else
"$$LK,\"%s\",A=\"FI:%s\"$$",filename,full_name;
"$$LK,\"%s\",A=\"FI:%s\"$$", filename, full_name;
}
Free(st);
}
}
}
U0 PutDirLink(U8 *dirname,U8 *full_name=NULL)
U0 PutDirLink(U8 *dirname, U8 *full_name=NULL)
{//Put $LK,"DolDoc",A="FI:::/Doc/DolDocOverview.DD"$ dir macro to StdOut, $LK,"DocPut",A="MN:DocPut"$.
U8 *st;
if (!dirname) return;
if (!dirname)
return;
if (IsRaw)
"%s",dirname;
else {
"%s", dirname;
else
{
if (!full_name)
full_name=st=DirNameAbs(dirname);
full_name = st = DirNameAbs(dirname);
else
st=NULL;
"$$MA,T=\"%s\",LM=\"Cd(\\\"%s\\\");Dir;\n\"$$",dirname,full_name;
st = NULL;
"$$MA,T=\"%s\",LM=\"Cd(\\\"%s\\\");Dir;\n\"$$", dirname, full_name;
Free(st);
}
}

View file

@ -1,83 +1,96 @@
U0 HomeSet(U8 *dirname)
{//Change home directory.
dirname=DirNameAbs(dirname);
dirname = DirNameAbs(dirname);
Free(blkdev.home_dir);
blkdev.home_dir=ZStrNew(dirname);
blkdev.home_dir = ZStrNew(dirname);
Free(dirname);
}
Bool Cd(U8 *dirname=NULL,Bool make_dirs=FALSE)
Bool Cd(U8 *dirname=NULL, Bool make_dirs=FALSE)
{//Change directory. Optionally, make directories, too.
I64 maxlen,cur_dir_clus=0;
U8 *chg_to_buf,*new_cur_dir,*buf;
CDrive *drive;
Bool res=TRUE;
I64 maxlen, cur_dir_clus = 0;
U8 *chg_to_buf, *new_cur_dir, *buf;
CDrive *drive;
Bool res = TRUE;
if (!dirname)
dirname="~";
dirname = "~";
else if (!*dirname)
return TRUE;
if (dirname[1]==':') {
if (*dirname==':') {
if (Fs->cur_dv!=Letter2Drive(':') && !Drive(*dirname))
if (dirname[1] == ':')
{
if (*dirname == ':')
{
if (Fs->cur_dv != Letter2Drive(':') && !Drive(*dirname))
return FALSE;
} else if (Fs->cur_dv!=Letter2Drive(*dirname) && !Drive(*dirname))
}
else if (Fs->cur_dv != Letter2Drive(*dirname) && !Drive(*dirname))
return FALSE;
dirname+=2;
dirname += 2;
}
if (*dirname=='/' || !*dirname || !Fs->cur_dir) {
if (*dirname == '/' || !*dirname || !Fs->cur_dir)
{
Free(Fs->cur_dir);
Fs->cur_dir=StrNew("/");
if (*dirname=='/')
Fs->cur_dir = StrNew("/");
if (*dirname == '/')
dirname++;
}
chg_to_buf=MStrUtil(dirname,
SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
maxlen=StrLen(Fs->cur_dir)+1+StrLen(chg_to_buf)+1;
new_cur_dir=MAlloc(maxlen);
buf=MAlloc(maxlen);
StrCopy(new_cur_dir,Fs->cur_dir);
while (*chg_to_buf && res) {
StrFirstRemove(chg_to_buf,"/",buf);
chg_to_buf = MStrUtil(dirname, SUF_REM_LEADING | SUF_REM_TRAILING | SUF_REM_CTRL_CHARS);
maxlen = StrLen(Fs->cur_dir) + 1 + StrLen(chg_to_buf) + 1;
new_cur_dir = MAlloc(maxlen);
buf = MAlloc(maxlen);
StrCopy(new_cur_dir, Fs->cur_dir);
while (*chg_to_buf && res)
{
StrFirstRemove(chg_to_buf, "/", buf);
if (!*buf)
StrCopy(new_cur_dir,"/");
else if (!StrCompare(buf,"..")) {
StrLastRemove(new_cur_dir,"/");
StrCopy(new_cur_dir, "/");
else if (!StrCompare(buf, ".."))
{
StrLastRemove(new_cur_dir, "/");
if (!*new_cur_dir)
StrCopy(new_cur_dir,"/");
} else if (!StrCompare(buf,"~")) {
StrCopy(new_cur_dir, "/");
}
else if (!StrCompare(buf, "~"))
{
Free(new_cur_dir);
new_cur_dir=MAlloc(StrLen(blkdev.home_dir+2)+1+StrLen(chg_to_buf)+1);
StrCopy(new_cur_dir,blkdev.home_dir+2);
if (Fs->cur_dv!=Letter2Drive('~') && !Drive('~'))
new_cur_dir = MAlloc(StrLen(blkdev.home_dir + 2) + 1 + StrLen(chg_to_buf) + 1);
StrCopy(new_cur_dir, blkdev.home_dir + 2);
if (Fs->cur_dv != Letter2Drive('~') && !Drive('~'))
return FALSE;
} else if (StrCompare(buf,".") && *buf) {
drive=Fs->cur_dv;
cur_dir_clus=Name2DirClus(drive,new_cur_dir);
switch (drive->fs_type) {
}
else if (StrCompare(buf, ".") && *buf)
{
drive = Fs->cur_dv;
cur_dir_clus = Name2DirClus(drive, new_cur_dir);
switch (drive->fs_type)
{
case FSt_REDSEA:
res=RedSeaCd(buf,cur_dir_clus);
res = RedSeaCd(buf, cur_dir_clus);
break;
case FSt_FAT32:
res=FAT32Cd(buf,cur_dir_clus);
res = FAT32Cd(buf, cur_dir_clus);
break;
default:
PrintErr("File System Not Supported\n");
res=FALSE;
res = FALSE;
}
if (!res && make_dirs) {
if (!res && make_dirs)
{
Free(Fs->cur_dir);
Fs->cur_dir=StrNew(new_cur_dir);
res=DirMake(buf);
Fs->cur_dir = StrNew(new_cur_dir);
res = DirMake(buf);
}
if (res) {
if (StrCompare(new_cur_dir,"/"))
CatPrint(new_cur_dir,"/");
CatPrint(new_cur_dir,buf);
if (res)
{
if (StrCompare(new_cur_dir, "/"))
CatPrint(new_cur_dir, "/");
CatPrint(new_cur_dir, buf);
}
}
}
Free(Fs->cur_dir);
Fs->cur_dir=StrNew(new_cur_dir);
Fs->cur_dir = StrNew(new_cur_dir);
Free(buf);
Free(chg_to_buf);
Free(new_cur_dir);
@ -86,101 +99,112 @@ Bool Cd(U8 *dirname=NULL,Bool make_dirs=FALSE)
Bool IsDir(U8 *dir_name)
{//Is a str a valid, existing Dir?
U8 *mask=MStrPrint("%s/*",dir_name);
Bool res,old_silent=Silent;
CDirContext *dirc;
if (dirc=DirContextNew(mask)) {
U8 *mask = MStrPrint("%s/*", dir_name);
Bool res, old_silent = Silent;
CDirContext *dirc;
if (dirc = DirContextNew(mask))
{
DirContextDel(dirc);
res=TRUE;
} else
res=FALSE;
res = TRUE;
}
else
res = FALSE;
Free(mask);
Silent(old_silent);
return res;
}
I64 Dir(U8 *files_find_mask,Bool full)
I64 Dir(U8 *files_find_mask, Bool full)
{//List directory.
CDirEntry *tmpde1=NULL,*tmpde2;
U8 *st;
CDateStruct ds;
I64 csize=0xFFFF,c=0xFFFF,res=0;
tmpde1=FilesFind(files_find_mask);
if (!(st=DirCur))
PrintErr("Invalid Drive\n");
else {
if (tmpde1) {
Free(st);
st=MAllocIdent(tmpde1->full_name);
StrLastRemove(st,"/");
if (!st[2])
StrCopy(st+2,"/");
//Find max columns
tmpde2=tmpde1;
while (tmpde2) {
if (tmpde2->size>csize)
csize=tmpde2->size;
if (tmpde2->clus>c)
c=tmpde2->clus;
tmpde2=tmpde2->next;
}
csize=Bsr(csize)/4+1;
c=Bsr(c)/4+1;
CDirEntry *tmpde1 = NULL, *tmpde2;
U8 *st;
CDateStruct ds;
I64 csize = 0xFFFF, c = 0xFFFF, res = 0;
"$$MA,T=\"Directory\",LM=\"PopUpCd;Dir;\n\"$$ of %s\n",st;
tmpde1 = FilesFind(files_find_mask);
if (!(st = DirCur))
PrintErr("Invalid Drive\n");
else
{
if (tmpde1)
{
Free(st);
st = MAllocIdent(tmpde1->full_name);
StrLastRemove(st, "/");
if (!st[2])
StrCopy(st + 2, "/");
//Find max columns
tmpde2 = tmpde1;
while (tmpde2)
{
if (tmpde2->size > csize)
csize = tmpde2->size;
if (tmpde2->clus > c)
c = tmpde2->clus;
tmpde2 = tmpde2->next;
}
csize = Bsr(csize) / 4 + 1;
c = Bsr(c) / 4 + 1;
"$$MA,T=\"Directory\",LM=\"PopUpCd;Dir;\n\"$$ of %s\n", st;
if (full)
"__DATE__ __TIME__ %*ts %*ts\n",
csize,"SIZE",c,"BLK";
"__DATE__ __TIME__ %*ts %*ts\n", csize, "SIZE", c, "BLK";
else
"DATE_ TIME_ %*ts\n",csize,"SIZE";
while (tmpde1) {
tmpde2=tmpde1->next;
"DATE_ TIME_ %*ts\n", csize, "SIZE";
while (tmpde1)
{
tmpde2 = tmpde1->next;
res++;
if (full)
"%D %T %0*tX %0*tX ",tmpde1->datetime,tmpde1->datetime,
csize,tmpde1->size,c,tmpde1->clus;
else {
Date2Struct(&ds,tmpde1->datetime+local_time_offset);
"%02d/%02d %02d:%02d %0*tX ",ds.mon,ds.day_of_mon,ds.hour,ds.min,
csize,tmpde1->size;
"%D %T %0*tX %0*tX ", tmpde1->datetime, tmpde1->datetime, csize, tmpde1->size, c, tmpde1->clus;
else
{
Date2Struct(&ds, tmpde1->datetime + local_time_offset);
"%02d/%02d %02d:%02d %0*tX ", ds.mon, ds.day_of_mon, ds.hour, ds.min, csize, tmpde1->size;
}
if (tmpde1->attr & RS_ATTR_DIR)
PutDirLink(tmpde1->name,tmpde1->full_name);
PutDirLink(tmpde1->name, tmpde1->full_name);
else
PutFileLink(tmpde1->name,tmpde1->full_name);
PutFileLink(tmpde1->name, tmpde1->full_name);
'\n';
DirEntryDel(tmpde1);
tmpde1=tmpde2;
tmpde1 = tmpde2;
}
} else
}
else
"No matching entries\n";
Free(st);
}
return res;
}
Bool DirMake(U8 *filename,I64 entry_count=0)
Bool DirMake(U8 *filename, I64 entry_count=0)
{//Make directory. $LK,"Cd",A="MN:Cd"$() can also make directories.
//entry_count is for preallocating dir blks, leave it zero if you like.
U8 *name;
CDirContext *dirc;
Bool res=FALSE;
if (FileFind(filename,,FUF_JUST_DIRS))
U8 *name;
CDirContext *dirc;
Bool res = FALSE;
if (FileFind(filename,, FUF_JUST_DIRS))
return FALSE;
if (dirc=DirContextNew(filename)) {
if (*dirc->mask) {
if (dirc = DirContextNew(filename))
{
if (*dirc->mask)
{
if (!FileNameCheck(dirc->mask))
PrintErr("Invalid FileName: \"%s\".\n",dirc->mask);
else {
"Make Directory:%s\n",filename;
name=MStrUtil(dirc->mask,
SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
switch (dirc->drive->fs_type) {
PrintErr("Invalid FileName: \"%s\".\n", dirc->mask);
else
{
"Make Directory:%s\n", filename;
name = MStrUtil(dirc->mask, SUF_REM_LEADING | SUF_REM_TRAILING | SUF_REM_CTRL_CHARS);
switch (dirc->drive->fs_type)
{
case FSt_REDSEA:
res=RedSeaMkDir(dirc->drive,Fs->cur_dir,name,entry_count);
res = RedSeaMkDir(dirc->drive, Fs->cur_dir, name, entry_count);
break;
case FSt_FAT32:
res=FAT32MkDir(dirc->drive,Fs->cur_dir,name,entry_count);
res = FAT32MkDir(dirc->drive, Fs->cur_dir, name, entry_count);
break;
default:
PrintErr("File System Not Supported\n");

View file

@ -1,18 +1,25 @@
U0 DirContextDel(CDirContext *dirc,Bool restore=TRUE)
U0 DirContextDel(CDirContext *dirc, Bool restore=TRUE)
{//Change back to old cur_dir and drv.
CBlkDev *bd;
if (!dirc) return;
if (restore) {
bd=dirc->old_dv->bd;
if (!(bd->flags & BDF_INIT_IN_PROGRESS)) {
if (dirc->old_dir) {
if (!dirc)
return;
if (restore)
{
bd = dirc->old_dv->bd;
if (!(bd->flags & BDF_INIT_IN_PROGRESS))
{
if (dirc->old_dir)
{
Drive(Drive2Letter(dirc->old_dv));
Cd(dirc->old_dir);
}
} else {
Fs->cur_dv=dirc->old_dv;
}
else
{
Fs->cur_dv = dirc->old_dv;
Free(Fs->cur_dir);
Fs->cur_dir=StrNew("/");
Fs->cur_dir = StrNew("/");
}
}
Free(dirc->old_dir);
@ -20,58 +27,67 @@ U0 DirContextDel(CDirContext *dirc,Bool restore=TRUE)
Free(dirc);
}
CDirContext *DirContextNew(U8 *_mask,Bool make_mask=FALSE,
Bool make_dirs=FALSE,Bool no_mask=FALSE)
CDirContext *DirContextNew(U8 *_mask, Bool make_mask=FALSE, Bool make_dirs=FALSE, Bool no_mask=FALSE)
{//Save cur_dir and drv. Change to new dir.
Bool valid=TRUE,old_silent;
I64 mask_len=StrLen(_mask);
U8 *buf,*mask,*tmp_mask,*semicolon_mask;
CDirContext *dirc=CAlloc(sizeof(CDirContext));
dirc->old_dir=StrNew(Fs->cur_dir);
dirc->old_dv=Fs->cur_dv;
mask=MStrUtil(_mask,SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
tmp_mask=mask;
if (*mask && mask[1]==':') {
if (Fs->cur_dv!=Letter2Drive(*mask) && !Drive(*mask))
valid=FALSE;
mask+=2;
Bool valid = TRUE, old_silent;
I64 mask_len = StrLen(_mask);
U8 *buf, *mask, *tmp_mask, *semicolon_mask;
CDirContext *dirc = CAlloc(sizeof(CDirContext));
dirc->old_dir = StrNew(Fs->cur_dir);
dirc->old_dv = Fs->cur_dv;
mask = MStrUtil(_mask, SUF_REM_LEADING | SUF_REM_TRAILING | SUF_REM_CTRL_CHARS);
tmp_mask = mask;
if (*mask && mask[1] == ':')
{
if (Fs->cur_dv != Letter2Drive(*mask) && !Drive(*mask))
valid = FALSE;
mask += 2;
}
if (*mask=='~' && Fs->cur_dv!=Letter2Drive('~') && !Drive('~'))
valid=FALSE;
dirc->drive=Fs->cur_dv;
if (*mask == '~' && Fs->cur_dv != Letter2Drive('~') && !Drive('~'))
valid = FALSE;
dirc->drive = Fs->cur_dv;
DriveCheck(dirc->drive);
buf=MAlloc(mask_len+2);
StrCopy(buf,mask);
buf = MAlloc(mask_len + 2);
StrCopy(buf, mask);
dirc->mask=MAlloc(mask_len+2);
dirc->mask = MAlloc(mask_len + 2);
if (no_mask)
*dirc->mask=0;
else if (StrOcc(buf,';')) {
semicolon_mask=MAlloc(mask_len+2);
StrCopy(semicolon_mask,mask);
StrFirstRemove(semicolon_mask,";",buf);
StrLastRemove(buf,"/",dirc->mask);
CatPrint(dirc->mask,";%s",semicolon_mask);
*dirc->mask = 0;
else if (StrOcc(buf, ';'))
{
semicolon_mask = MAlloc(mask_len + 2);
StrCopy(semicolon_mask, mask);
StrFirstRemove(semicolon_mask, ";", buf);
StrLastRemove(buf, "/", dirc->mask);
CatPrint(dirc->mask, ";%s", semicolon_mask);
Free(semicolon_mask);
} else
StrLastRemove(buf,"/",dirc->mask);
}
else
StrLastRemove(buf, "/", dirc->mask);
if (*mask=='/' && !*buf)
StrCopy(buf,"/");
if (*mask == '/' && !*buf)
StrCopy(buf, "/");
//If began with Dir, change to Dir.
if (*buf && !Cd(buf,make_dirs))
valid=FALSE;
if (valid && make_mask) {
if (!*dirc->mask) {
if (*buf && !Cd(buf, make_dirs))
valid = FALSE;
if (valid && make_mask)
{
if (!*dirc->mask)
{
Free(dirc->mask);
dirc->mask=StrNew("*");
} else {
if (!make_dirs || FileNameCheck(dirc->mask)) {
old_silent=Silent;
dirc->mask = StrNew("*");
}
else
{
if (!make_dirs || FileNameCheck(dirc->mask))
{
old_silent = Silent;
//Try mask to see if Dir. If Dir, change to dir and set to "*".
if (Cd(dirc->mask,make_dirs)) {
if (Cd(dirc->mask, make_dirs))
{
Free(dirc->mask);
dirc->mask=StrNew("*");
dirc->mask = StrNew("*");
}
Silent(old_silent);
}
@ -79,9 +95,10 @@ CDirContext *DirContextNew(U8 *_mask,Bool make_mask=FALSE,
}
Free(buf);
Free(tmp_mask);
if (!valid) {
if (!valid)
{
DirContextDel(dirc);
dirc=NULL;
dirc = NULL;
}
return dirc;
}

View file

@ -2,86 +2,97 @@ Bool DriveLock(CDrive *drive)
{//Make this task have exclusive access to drv & BlkDev.
DriveCheck(drive);
BlkDevLock(drive->bd);
if (!Bt(&drive->locked_flags,DVlf_LOCKED) || drive->owning_task!=Fs) {
while (LBts(&drive->locked_flags,DVlf_LOCKED))
if (!Bt(&drive->locked_flags, DVlf_LOCKED) || drive->owning_task != Fs)
{
while (LBts(&drive->locked_flags, DVlf_LOCKED))
Yield;
drive->owning_task=Fs;
drive->owning_task = Fs;
return TRUE;
} else
}
else
return FALSE;
}
Bool DriveUnlock(CDrive *drive,Bool reset=FALSE)
Bool DriveUnlock(CDrive *drive, Bool reset=FALSE)
{//Release exclusive lock on access to drv & BlkDev.
DriveCheck(drive);
if (Bt(&drive->locked_flags,DVlf_LOCKED) && drive->owning_task==Fs) {
BlkDevUnlock(drive->bd,reset);
drive->owning_task=NULL;
LBtr(&drive->locked_flags,DVlf_LOCKED);
if (Bt(&drive->locked_flags, DVlf_LOCKED) && drive->owning_task == Fs)
{
BlkDevUnlock(drive->bd, reset);
drive->owning_task = NULL;
LBtr(&drive->locked_flags, DVlf_LOCKED);
Yield; //Prevent deadlock
return TRUE;
} else
}
else
return FALSE;
}
U0 DrivesRelease()
{//When task dies, release all owned drvs.
I64 i;
CDrive *drive;
for (i=0;i<DRIVES_NUM;i++) {
drive=&blkdev.drvs[i];
if (drive->owning_task==Fs && drive->drive_signature==DRIVE_SIGNATURE_VAL)
DriveUnlock(drive,TRUE);
I64 i;
CDrive *drive;
for (i = 0; i < DRIVES_NUM; i++)
{
drive = &blkdev.drvs[i];
if (drive->owning_task == Fs && drive->drive_signature == DRIVE_SIGNATURE_VAL)
DriveUnlock(drive, TRUE);
}
}
CDrive *DriveMakeFreeSlot(U8 drv_let)
{//Make a slot free for a new drv, like during $LK,"Mount",A="MN:Mount"$().
//!!! drv_let is not a $LK,"remapped",A="MN:DriveMap"$ drv.
I64 i=Letter2Letter(drv_let)-'A';
CDrive *res;
if (!(0<=i<DRIVES_NUM))
I64 i = Letter2Letter(drv_let) - 'A';
CDrive *res;
if (!(0 <= i < DRIVES_NUM))
throw('Drive');
res=&blkdev.drvs[i];
MemSet(res,0,sizeof(CDrive));
res->drv_let='A'+i;
res = &blkdev.drvs[i];
MemSet(res, 0, sizeof(CDrive));
res->drv_let = 'A' + i;
return res;
}
U8 DriveNextFreeLet(U8 first_drive_let='C')
{//Locate free slot for new drv, like during $LK,"Mount",A="MN:Mount"$().
//!!! first_drive_let is not a $LK,"remapped",A="MN:DriveMap"$ drv.
I64 i=Letter2Letter(first_drive_let)-'A',type=Letter2BlkDevType(first_drive_let);
if (!(0<=i<DRIVES_NUM))
I64 i = Letter2Letter(first_drive_let) - 'A', type = Letter2BlkDevType(first_drive_let);
if (!(0 <= i < DRIVES_NUM))
throw('Drive');
do
if (blkdev.drvs[i].drive_signature!=DRIVE_SIGNATURE_VAL) {
if (Letter2BlkDevType(i+'A')!=type)
if (blkdev.drvs[i].drive_signature != DRIVE_SIGNATURE_VAL)
{
if (Letter2BlkDevType(i + 'A') != type)
throw('Drive');
else
return i+'A';
return i + 'A';
}
while (++i<DRIVES_NUM);
while (++i < DRIVES_NUM);
throw('Drive');
return 0; //Never gets here.
}
U0 DriveDel(CDrive *drive)
{//Delete drv
if (drive->fs_type==FSt_REDSEA && drive->next_free)
if (drive->fs_type == FSt_REDSEA && drive->next_free)
RedSeaFreeFreeList(drive);
Free(drive->cur_fat_blk);
Free(drive->fis);
MemSet(drive,0,sizeof(CDrive));
MemSet(drive, 0, sizeof(CDrive));
}
U0 DriveBlkDevDel(CBlkDev *bd)
{//Delete drv's of BlkDev
I64 i;
CDrive *drive;
for (i=0;i<DRIVES_NUM;i++) {
drive=&blkdev.drvs[i];
if (drive->bd==bd)
I64 i;
CDrive *drive;
for (i = 0; i < DRIVES_NUM; i++)
{
drive = &blkdev.drvs[i];
if (drive->bd == bd)
DriveDel(drive);
}
}
@ -90,70 +101,79 @@ U0 DriveFATBlkAlloc(CDrive *drive)
{
DriveCheck(drive);
Free(drive->cur_fat_blk);
drive->cur_fat_blk=ZMAlloc(BLK_SIZE);
drive->cur_fat_blk_num=0;
drive->fat_blk_dirty=0;
BlkRead(drive,drive->cur_fat_blk,drive->fat1,1);
drive->cur_fat_blk = ZMAlloc(BLK_SIZE);
drive->cur_fat_blk_num = 0;
drive->fat_blk_dirty = 0;
BlkRead(drive, drive->cur_fat_blk, drive->fat1, 1);
}
U0 DriveFATBlkClean(CDrive *drive,I64 fat_sel=3)
U0 DriveFATBlkClean(CDrive *drive, I64 fat_sel=3)
{
if ((drive->fs_type==FSt_FAT32 || drive->fs_type==FSt_REDSEA) &&
Bt(&drive->fat_blk_dirty,0)) {
if (drive->fat1==drive->fat2) {
BlkWrite(drive,drive->cur_fat_blk,drive->fat1+drive->cur_fat_blk_num,1);
LBtr(&drive->fat_blk_dirty,0);
} else {
if (fat_sel==3 || !fat_sel)
BlkWrite(drive,drive->cur_fat_blk,drive->fat1+drive->cur_fat_blk_num,1);
if (fat_sel==3 || fat_sel==1) {
BlkWrite(drive,drive->cur_fat_blk,drive->fat2+drive->cur_fat_blk_num,1);
LBtr(&drive->fat_blk_dirty,0);
if ((drive->fs_type == FSt_FAT32 || drive->fs_type == FSt_REDSEA) && Bt(&drive->fat_blk_dirty, 0))
{
if (drive->fat1 == drive->fat2)
{
BlkWrite(drive, drive->cur_fat_blk, drive->fat1 + drive->cur_fat_blk_num, 1);
LBtr(&drive->fat_blk_dirty, 0);
}
else
{
if (fat_sel == 3 || !fat_sel)
BlkWrite(drive, drive->cur_fat_blk, drive->fat1 + drive->cur_fat_blk_num, 1);
if (fat_sel == 3 || fat_sel == 1)
{
BlkWrite(drive, drive->cur_fat_blk, drive->fat2 + drive->cur_fat_blk_num, 1);
LBtr(&drive->fat_blk_dirty, 0);
}
}
}
}
U0 DriveFATBlkSet(CDrive *drive,I64 c,I64 fat_sel=3)
U0 DriveFATBlkSet(CDrive *drive, I64 c, I64 fat_sel=3)
{
I64 fat_blk_num;
if (c==INVALID_CLUS)
if (c == INVALID_CLUS)
throw('Drive');
switch (drive->fs_type) {
switch (drive->fs_type)
{
case FSt_FAT32:
fat_blk_num=c>>(BLK_SIZE_BITS-2);
fat_blk_num = c >> (BLK_SIZE_BITS - 2);
break;
case FSt_REDSEA:
fat_blk_num=(c-drive->data_area)>>(BLK_SIZE_BITS+3);
fat_blk_num = (c-drive->data_area) >> (BLK_SIZE_BITS + 3);
break;
default:
throw('Drive');
}
if (fat_blk_num!=drive->cur_fat_blk_num) {
DriveFATBlkClean(drive,fat_sel);
drive->cur_fat_blk_num=fat_blk_num;
if (fat_sel==3 || !fat_sel)
BlkRead(drive,drive->cur_fat_blk,drive->fat1+drive->cur_fat_blk_num,1);
if (fat_blk_num != drive->cur_fat_blk_num)
{
DriveFATBlkClean(drive, fat_sel);
drive->cur_fat_blk_num = fat_blk_num;
if (fat_sel == 3 || !fat_sel)
BlkRead(drive, drive->cur_fat_blk, drive->fat1 + drive->cur_fat_blk_num, 1);
else
BlkRead(drive,drive->cur_fat_blk,drive->fat2+drive->cur_fat_blk_num,1);
BlkRead(drive, drive->cur_fat_blk, drive->fat2 + drive->cur_fat_blk_num, 1);
}
}
CDrive *DriveCheck(CDrive *drive,Bool except=TRUE)
CDrive *DriveCheck(CDrive *drive, Bool except=TRUE)
{//Check for valid drv. Throw exception.
if (!drive || drive->drive_signature!=DRIVE_SIGNATURE_VAL) {
if (!drive || drive->drive_signature != DRIVE_SIGNATURE_VAL)
{
if (except)
throw('Drive');
else
return NULL;
} else
}
else
return drive;
}
U8 Drive2Letter(CDrive *drive=NULL)
{//Drive ptr to Drive letter.
if (!drive)
drive=Fs->cur_dv;
drive = Fs->cur_dv;
DriveCheck(drive);
return drive->drv_let;
}
@ -161,87 +181,101 @@ U8 Drive2Letter(CDrive *drive=NULL)
U8 Letter2Letter(U8 drv_let=0)
{//Drive letter to Drive letter.
if (!drv_let)
drv_let=Drive2Letter(Fs->cur_dv);
else if (drv_let==':')
drv_let=blkdev.boot_drive_let;
else if (drv_let=='~')
drv_let=*blkdev.home_dir;
drv_let = Drive2Letter(Fs->cur_dv);
else if (drv_let == ':')
drv_let = blkdev.boot_drive_let;
else if (drv_let == '~')
drv_let = *blkdev.home_dir;
return ToUpper(drv_let);
}
I64 Letter2BlkDevType(U8 drv_let)
{//Drive letter to BlkDev Type. drv_let=0 not allowed. See $LK,"BDT_NULL",A="MN:BDT_NULL"$.
drv_let=Letter2Letter(drv_let);
if ('A'<=drv_let<='B')
drv_let = Letter2Letter(drv_let);
if ('A' <= drv_let <= 'B')
return BDT_RAM;
if ('C'<=drv_let<='L')
if ('C' <= drv_let <= 'L')
return BDT_ATA;
if ('M'<=drv_let<='P')
if ('M' <= drv_let <= 'P')
return BDT_ISO_FILE_READ;
if ('Q'<=drv_let<='S')
if ('Q' <= drv_let <= 'S')
return BDT_ISO_FILE_WRITE;
if ('T'<=drv_let<='Z')
if ('T' <= drv_let <= 'Z')
return BDT_ATAPI;
return BDT_NULL;
}
CDrive *Letter2Drive(U8 drv_let=0,Bool except=TRUE)
CDrive *Letter2Drive(U8 drv_let=0, Bool except=TRUE)
{//Drive letter to Drive ptr.
CDrive *drive;
if (!drv_let)
drive=Fs->cur_dv;
else {
drv_let=Letter2Letter(drv_let);
if (!('A'<=drv_let<='Z')) {
drive = Fs->cur_dv;
else
{
drv_let = Letter2Letter(drv_let);
if (!('A' <= drv_let <= 'Z'))
{
if (except)
throw('Drive');
else
return NULL;
}
drive=blkdev.let_to_drive[drv_let-'A'];
drive = blkdev.let_to_drive[drv_let - 'A'];
}
return DriveCheck(drive,except);
return DriveCheck(drive, except);
}
CBlkDev *DriveIsWritable(U8 drv_let=0,Bool except=FALSE)
CBlkDev *DriveIsWritable(U8 drv_let=0, Bool except=FALSE)
{//Is drive writable?
CBlkDev *bd;
if (!(bd=Letter2BlkDev(drv_let,except)) || bd->flags & BDF_READ_ONLY) {
if (!(bd = Letter2BlkDev(drv_let, except)) || bd->flags & BDF_READ_ONLY)
{
if (except)
throw('Drive');
else
return NULL;
} else
}
else
return bd;
}
U0 DiskCacheInvalidate(CDrive *drive)
{//Needed for removable media. Called by $LK,"DiskChange",A="MN:DiskChange"$().
Bool unlock;
CBlkDev *bd=drive->bd;
Bool unlock;
CBlkDev *bd = drive->bd;
DriveCheck(drive);
try {
unlock=DriveLock(drive);
try
{
unlock = DriveLock(drive);
BlkDevInit(bd);
if (bd->flags & BDF_READ_CACHE)
DiskCacheInvalidate2(drive);
if (bd->type==BDT_ATAPI && !(bd->flags & BDF_READ_ONLY_OVERRIDE))
ISOInit(drive,(32767/bd->blk_size+1)*bd->blk_size>>BLK_SIZE_BITS);
if (bd->type == BDT_ATAPI && !(bd->flags & BDF_READ_ONLY_OVERRIDE))
ISOInit(drive, (32767 / bd->blk_size + 1) * bd->blk_size >> BLK_SIZE_BITS);
if (unlock)
DriveUnlock(drive);
} catch
}
catch
if (unlock)
DriveUnlock(drive);
}
U0 DiskChange(U8 drv_let=0)
{//Change disk. (Needed for removable media.)
CDrive *drive=Letter2Drive(drv_let);
CBlkDev *bd=drive->bd;
if (!(bd->flags&BDF_INITIALIZED))
CDrive *drive = Letter2Drive(drv_let);
CBlkDev *bd = drive->bd;
if (!(bd->flags & BDF_INITIALIZED))
BlkDevInit(bd);
else if (bd->flags&BDF_REMOVABLE) {
if (bd->type==BDT_ATAPI)
else if (bd->flags & BDF_REMOVABLE)
{
if (bd->type == BDT_ATAPI)
ATAInit(bd); //TODO: This is a kludge for QEMU?
DiskCacheInvalidate(drive);
}
@ -249,33 +283,37 @@ U0 DiskChange(U8 drv_let=0)
RedSeaFreeFreeList(drive);
}
Bool DriveMap(U8 drv_let,CDrive *drive)
Bool DriveMap(U8 drv_let, CDrive *drive)
{//Make drive letter map to another.
drv_let=Letter2Letter(drv_let);
if ('A'<=drv_let<='Z') {
blkdev.let_to_drive[drv_let-'A']=drive;
drive->drv_let=drv_let;
drv_let = Letter2Letter(drv_let);
if ('A' <= drv_let <= 'Z')
{
blkdev.let_to_drive[drv_let - 'A'] = drive;
drive->drv_let = drv_let;
return TRUE;
} else
}
else
return FALSE;
}
Bool Drive(U8 drv_let)
{//Change drive. You can set drive with $LK,"Cd",A="MN:Cd"$() as well.
CDrive *drive=Letter2Drive(drv_let);
CBlkDev *bd;
bd=BlkDevCheck(drive->bd);
if (drive!=Fs->cur_dv) {
CDrive *drive = Letter2Drive(drv_let);
CBlkDev *bd;
bd = BlkDevCheck(drive->bd);
if (drive != Fs->cur_dv)
{
if (bd->flags & BDF_REMOVABLE && !(bd->flags & BDF_INITIALIZED))
DiskChange(Drive2Letter(drive));
if (bd->type==BDT_RAM ||
bd->type==BDT_ISO_FILE_READ || bd->type==BDT_ISO_FILE_WRITE)
if (bd->type == BDT_RAM || bd->type == BDT_ISO_FILE_READ || bd->type == BDT_ISO_FILE_WRITE)
BlkDevInit(bd);
}
Fs->cur_dv=drive;
Fs->cur_dv = drive;
Free(Fs->cur_dir);
Fs->cur_dir=StrNew("/");
switch (drive->fs_type) {
Fs->cur_dir = StrNew("/");
switch (drive->fs_type)
{
case FSt_REDSEA:
case FSt_FAT32:
return TRUE;
@ -287,80 +325,96 @@ Bool Drive(U8 drv_let)
U8 *DriveSerialNum(U8 drv_let=0)
{//20 bytes max.
CBlkDev *bd=Letter2BlkDev(drv_let);
U16 *st,*res=NULL;
I64 i;
if (bd->dev_id_record) {
st=CAlloc(20+1);
for (i=0;i<10;i++)
st[i]=EndianU16(bd->dev_id_record[10+i]);
res=MStrUtil(st,SUF_REM_LEADING|SUF_REM_TRAILING);
CBlkDev *bd = Letter2BlkDev(drv_let);
U16 *st, *res = NULL;
I64 i;
if (bd->dev_id_record)
{
st = CAlloc(20 + 1);
for (i = 0; i < 10; i++)
st[i] = EndianU16(bd->dev_id_record[10 + i]);
res = MStrUtil(st, SUF_REM_LEADING | SUF_REM_TRAILING);
Free(st);
}
return res;
}
U8 *DriveModelNum(U8 drv_let=0)
{//40 bytes max.
CBlkDev *bd=Letter2BlkDev(drv_let);
U16 *st,*res=NULL;
I64 i;
if (bd->dev_id_record) {
st=CAlloc(40+1);
for (i=0;i<20;i++)
st[i]=EndianU16(bd->dev_id_record[27+i]);
res=MStrUtil(st,SUF_REM_LEADING|SUF_REM_TRAILING);
CBlkDev *bd = Letter2BlkDev(drv_let);
U16 *st, *res = NULL;
I64 i;
if (bd->dev_id_record)
{
st = CAlloc(40 + 1);
for (i = 0; i < 20; i++)
st[i] = EndianU16(bd->dev_id_record[27 + i]);
res = MStrUtil(st, SUF_REM_LEADING | SUF_REM_TRAILING);
Free(st);
}
return res;
}
U8 blkdev_text_attr[BDT_TYPES_NUM]={BLACK,LTCYAN,WHITE,LTGREEN,LTRED,LTBLUE};
U8 drv_text_attr[3]={BLACK,BLUE,RED};
U8 blkdev_text_attr[BDT_TYPES_NUM] = {BLACK, LTCYAN, WHITE, LTGREEN, LTRED, LTBLUE};
U8 drv_text_attr[3] = {BLACK, BLUE, RED};
U8 DriveTextAttrGet(U8 drv_let=0)
{//Get color of drive.
drv_let=Letter2Letter(drv_let);
if ('A'<=drv_let<='Z')
return blkdev_text_attr[Letter2BlkDevType(drv_let)]<<4|
drv_text_attr[drv_let%sizeof(drv_text_attr)];
drv_let = Letter2Letter(drv_let);
if ('A' <= drv_let <= 'Z')
return blkdev_text_attr[Letter2BlkDevType(drv_let)] << 4 | drv_text_attr[drv_let % sizeof(drv_text_attr)];
else
return BLACK<<4|WHITE;
return BLACK << 4 | WHITE;
}
U0 DriveRep()
{//Drive report.
CDrive *drive;
CBlkDev *bd;
I64 ch,i,drv_let,attr;
U8 *st;
CDrive *drive;
CBlkDev *bd;
I64 ch, i, drv_let, attr;
U8 *st;
"\nDefined Drives:\n";
for (i=0,drive=blkdev.drvs;i<DRIVES_NUM;i++,drive++) {
if (drive->drive_signature==DRIVE_SIGNATURE_VAL) {
bd=drive->bd;
drv_let=Drive2Letter(drive);
if (Bt(&drive->fs_type,FStf_DISABLE))
ch='-';
else if (drv_let==blkdev.boot_drive_let)
ch=':';
for (i = 0, drive = blkdev.drvs; i < DRIVES_NUM; i++, drive++)
{
if (drive->drive_signature == DRIVE_SIGNATURE_VAL)
{
bd = drive->bd;
drv_let = Drive2Letter(drive);
if (Bt(&drive->fs_type, FStf_DISABLE))
ch = '-';
else if (drv_let == blkdev.boot_drive_let)
ch = ':';
else
ch='+';
attr=DriveTextAttrGet(drv_let);
"$$FG,%d$$$$BG,%d$$%C %-8Z %-10Z %04X %04X %02X\n",
attr&15,attr>>4,drv_let,drive->fs_type&FSG_TYPE_MASK,"ST_DRIVE_TYPES",
bd->type,"ST_BLKDEV_TYPES",bd->base0,bd->base1,bd->unit;
if (st=DriveModelNum(drv_let)) {
" Model# :%s\n",st;
ch = '+';
attr = DriveTextAttrGet(drv_let);
"$$FG,%d$$$$BG,%d$$%C %-8Z %-10Z %04X %04X %02X\n", attr & 15,
attr >> 4,
drv_let,
drive->fs_type & FSG_TYPE_MASK,
"ST_DRIVE_TYPES",
bd->type,
"ST_BLKDEV_TYPES",
bd->base0,
bd->base1,
bd->unit;
if (st = DriveModelNum(drv_let))
{
" Model# :%s\n", st;
Free(st);
}
if (st=DriveSerialNum(drv_let)) {
" Serial#:%s\n",st;
if (st = DriveSerialNum(drv_let))
{
" Serial#:%s\n", st;
Free(st);
}
if (bd->type==BDT_ISO_FILE_READ || bd->type==BDT_ISO_FILE_WRITE)
" File=\"%s\"\n",bd->file_disk_name;
" %016X-%016X\n$$FG$$$$BG$$",drive->drv_offset,drive->drv_offset+drive->size-1;
if (bd->type == BDT_ISO_FILE_READ || bd->type == BDT_ISO_FILE_WRITE)
" File=\"%s\"\n", bd->file_disk_name;
" %016X-%016X\n$$FG$$$$BG$$", drive->drv_offset, drive->drv_offset + drive->size - 1;
}
}
"Home Dir:\"%s\"\n",blkdev.home_dir;
"Home Dir:\"%s\"\n", blkdev.home_dir;
}

View file

@ -1,15 +1,16 @@
U8 *FileRead(U8 *filename, I64 *_size=NULL, I64 *_attr=NULL)
{//Read whole file from disk.
CHashGeneric *tmph;
U8 *absname, *res = NULL;
I64 size= 0 , attr = 0;
CDirContext *dirc;
CHashGeneric *tmph;
U8 *absname, *res = NULL;
I64 size = 0, attr = 0;
CDirContext *dirc;
absname = FileNameAbs(filename);
if (tmph = HashFind(absname, zenith_task->hash_table, HTT_FILE))
{
size = tmph->user_data1;
res = MAlloc(size + 1);
MemCopy(res , tmph->user_data0, size);
MemCopy(res, tmph->user_data0, size);
res[size] = 0; //Terminate
attr = FileAttr(tmph->str, attr);
}
@ -34,12 +35,13 @@ U8 *FileRead(U8 *filename, I64 *_size=NULL, I64 *_attr=NULL)
if (!res)
{
if (dirc=DirContextNew(absname))
if (dirc = DirContextNew(absname))
{
while (!res && StrCompare(Fs->cur_dir, "/"))
{
Cd("..");
switch (Fs->cur_dv->fs_type) {
switch (Fs->cur_dv->fs_type)
{
case FSt_REDSEA:
res = RedSeaFileRead(dirc->drive, Fs->cur_dir, dirc->mask, &size, &attr);
break;
@ -58,23 +60,27 @@ U8 *FileRead(U8 *filename, I64 *_size=NULL, I64 *_attr=NULL)
if (res && attr & RS_ATTR_RESIDENT)
HashGenericAdd(absname, HTT_FILE, ZMAllocIdent(res), size, 0, zenith_task);
if (_attr) *_attr=attr;
if (_size) *_size=size;
if (_attr)
*_attr = attr;
if (_size)
*_size = size;
Free(absname);
return res;
}
I64 FileWrite(U8 *filename, U8 *fbuf, I64 size, CDate cdt=0, I64 attr=0)
{//Write whole file to disk.
I64 c = 0;
CHashGeneric *tmph;
CDirContext *dirc;
U8 *absname = FileNameAbs(filename);
I64 c = 0;
CHashGeneric *tmph;
CDirContext *dirc;
U8 *absname = FileNameAbs(filename);
if (dirc = DirContextNew(filename, FALSE, TRUE))
{
attr = FileAttr(dirc->mask, attr);
if (!cdt)
cdt=Now;
cdt = Now;
switch (dirc->drive->fs_type)
{
case FSt_REDSEA:
@ -96,10 +102,12 @@ I64 FileWrite(U8 *filename, U8 *fbuf, I64 size, CDate cdt=0, I64 attr=0)
}
else
HashRemDel(tmph, zenith_task->hash_table);
} else if (attr & RS_ATTR_RESIDENT)
}
else if (attr & RS_ATTR_RESIDENT)
HashGenericAdd(absname, HTT_FILE, ZMAllocIdent(fbuf), size, 0, zenith_task);
DirContextDel(dirc);
}
Free(absname);
return c;
}

View file

@ -1,24 +1,27 @@
CDirEntry *FilesFind2(U8 *files_find_mask, I64 fuf_flags)
{
CDrive *drive=Fs->cur_dv;
CDirEntry *res=NULL;
CDrive *drive = Fs->cur_dv;
CDirEntry *res = NULL;
DriveCheck(drive);
switch (drive->fs_type) {
switch (drive->fs_type)
{
case FSt_REDSEA:
res=RedSeaFilesFind(files_find_mask, fuf_flags);
res = RedSeaFilesFind(files_find_mask, fuf_flags);
break;
case FSt_FAT32:
res=FAT32FilesFind(files_find_mask, fuf_flags);
res = FAT32FilesFind(files_find_mask, fuf_flags);
break;
default:
PrintErr("File System Not Supported\n");
res=NULL;
res = NULL;
}
if (res) {
if (res)
{
DirFilesSort(&res, SK_NAME);
if (fuf_flags&(FUF_FLATTEN_TREE|FUF_JUST_FILES))
if (fuf_flags & (FUF_FLATTEN_TREE | FUF_JUST_FILES))
DirFilesFlatten(res, &res, fuf_flags);
if (fuf_flags&FUF_CLUS_ORDER)
if (fuf_flags & FUF_CLUS_ORDER)
DirFilesSort(&res, SK_CLUS);
}
return res;
@ -33,20 +36,26 @@ When done, you free with $LK,"DirEntryDel",A="MN:DirEntryDel"$(), $LK,"DirEntry
$LK,"DirTreeDel",A="MN:DirTreeDel"$() or $LK,"DirTreeDel2",A="MN:DirTreeDel2"$().
*/
CDirEntry *res;
CDirContext *dirc;
if (fuf_flags&~FUG_FILES_FIND)
CDirEntry *res;
CDirContext *dirc;
if (fuf_flags & ~FUG_FILES_FIND)
throw('FUF');
if (fuf_flags&FUF_SINGLE) {
res=MAlloc(sizeof(CDirEntry));
if (!FileFind(files_find_mask, res)) {
if (fuf_flags & FUF_SINGLE)
{
res = MAlloc(sizeof(CDirEntry));
if (!FileFind(files_find_mask, res))
{
Free(res);
return NULL;
}
} else if (dirc=DirContextNew(files_find_mask, TRUE)) {
res=FilesFind2(dirc->mask, fuf_flags);
}
else if (dirc = DirContextNew(files_find_mask, TRUE))
{
res = FilesFind2(dirc->mask, fuf_flags);
DirContextDel(dirc);
} else
}
else
return NULL;
return res;
}
@ -54,26 +63,27 @@ $LK,"DirTreeDel",A="MN:DirTreeDel"$() or $LK,"DirTreeDel2",A="MN:DirTreeDel2"$()
Bool FileFind(U8 *filename, CDirEntry *_de=NULL, I64 fuf_flags=0)
{//$LK,"FUF_JUST_DIRS",A="MN:FUF_JUST_DIRS"$, $LK,"FUF_JUST_FILES",A="MN:FUF_JUST_FILES"$, $LK,"FUF_SCAN_PARENTS",A="MN:FUF_SCAN_PARENTS"$
//If you pass _de, you must Free(_de->full_name);
I64 cur_dir_clus;
U8 *full_name = NULL;
CDirEntry de;
CDirContext *dirc;
Bool res = FALSE;
if (fuf_flags&~FUG_FILE_FIND)
I64 cur_dir_clus;
U8 *full_name = NULL;
CDirEntry de;
CDirContext *dirc;
Bool res = FALSE;
if (fuf_flags & ~FUG_FILE_FIND)
throw('FUF');
if (!filename || *filename && filename[1] == ':' && !Letter2Drive(*filename, FALSE))
return FALSE;
if (dirc = DirContextNew(filename))
{
cur_dir_clus=Name2DirClus(dirc->drive, Fs->cur_dir);
cur_dir_clus = Name2DirClus(dirc->drive, Fs->cur_dir);
switch (dirc->drive->fs_type)
{
case FSt_REDSEA:
res=RedSeaFileFind(dirc->drive, cur_dir_clus, dirc->mask, &de, fuf_flags);
res = RedSeaFileFind(dirc->drive, cur_dir_clus, dirc->mask, &de, fuf_flags);
break;
case FSt_FAT32:
res=FAT32FileFind(dirc->drive, cur_dir_clus, dirc->mask, &de, fuf_flags);
res = FAT32FileFind(dirc->drive, cur_dir_clus, dirc->mask, &de, fuf_flags);
break;
default:
PrintErr("File System Not Supported\n");
@ -81,45 +91,51 @@ Bool FileFind(U8 *filename, CDirEntry *_de=NULL, I64 fuf_flags=0)
if (res && _de)
{
if (StrCompare(Fs->cur_dir, "/"))
full_name=MStrPrint("%C:%s/%s", Drive2Letter(Fs->cur_dv), Fs->cur_dir, de.name);
full_name = MStrPrint("%C:%s/%s", Drive2Letter(Fs->cur_dv), Fs->cur_dir, de.name);
else
full_name=MStrPrint("%C:/%s", Drive2Letter(Fs->cur_dv), de.name);
full_name = MStrPrint("%C:/%s", Drive2Letter(Fs->cur_dv), de.name);
}
DirContextDel(dirc);
}
if (!res && fuf_flags & FUF_SCAN_PARENTS)
{
if (dirc=DirContextNew(filename))
if (dirc = DirContextNew(filename))
{
cur_dir_clus=Name2DirClus(dirc->drive, Fs->cur_dir);
while (!res && StrCompare(Fs->cur_dir, "/")) {
cur_dir_clus = Name2DirClus(dirc->drive, Fs->cur_dir);
while (!res && StrCompare(Fs->cur_dir, "/"))
{
Cd("..");
cur_dir_clus=Name2DirClus(dirc->drive, Fs->cur_dir);
switch (dirc->drive->fs_type) {
cur_dir_clus = Name2DirClus(dirc->drive, Fs->cur_dir);
switch (dirc->drive->fs_type)
{
case FSt_REDSEA:
res=RedSeaFileFind(dirc->drive, cur_dir_clus, dirc->mask, &de, fuf_flags);
res = RedSeaFileFind(dirc->drive, cur_dir_clus, dirc->mask, &de, fuf_flags);
break;
case FSt_FAT32:
res=FAT32FileFind(dirc->drive, cur_dir_clus, dirc->mask, &de, fuf_flags);
res = FAT32FileFind(dirc->drive, cur_dir_clus, dirc->mask, &de, fuf_flags);
break;
default:
PrintErr("File System Not Supported\n");
}
}
if (res && _de) {
if (res && _de)
{
if (StrCompare(Fs->cur_dir, "/"))
full_name=MStrPrint("%C:%s/%s", Drive2Letter(Fs->cur_dv), Fs->cur_dir, de.name);
full_name = MStrPrint("%C:%s/%s", Drive2Letter(Fs->cur_dv), Fs->cur_dir, de.name);
else
full_name=MStrPrint("%C:/%s", Drive2Letter(Fs->cur_dv), de.name);
full_name = MStrPrint("%C:/%s", Drive2Letter(Fs->cur_dv), de.name);
}
DirContextDel(dirc);
}
}
if (_de) {
if (res) {
if (_de)
{
if (res)
{
MemCopy(_de, &de, sizeof(CDirEntry));
_de->full_name=full_name;
} else
_de->full_name = full_name;
}
else
MemSet(_de, 0, sizeof(CDirEntry));
}
return res;

View file

@ -1,78 +1,92 @@
Bool DriveTypeSet(U8 drv_let,I64 type=FSt_REDSEA)
Bool DriveTypeSet(U8 drv_let, I64 type=FSt_REDSEA)
{//Very dangerous
I64 i,j,ext_base,drv_num,offset,cur_type;
CMasterBoot mbr;
CBlkDev *bd;
drv_let=Letter2Letter(drv_let);
bd=Letter2BlkDev(drv_let);
drv_num=bd->first_drive_let-'A';
switch (bd->type) {
I64 i, j, ext_base, drv_num, offset, cur_type;
CMasterBoot mbr;
CBlkDev *bd;
drv_let = Letter2Letter(drv_let);
bd = Letter2BlkDev(drv_let);
drv_num = bd->first_drive_let - 'A';
switch (bd->type)
{
case BDT_ATA:
offset=0;
ext_base=INVALID_CLUS;
while (TRUE) {
ATAReadBlks(bd,&mbr,offset,1);
j=-1;
for (i=0;i<4;i++) {
cur_type=mbr.p[i].type;
if (cur_type) {
if (cur_type==5 || cur_type==15)
j=i;
else {
if (drv_num+'A'==drv_let) {
switch (type) {
offset = 0;
ext_base = INVALID_CLUS;
while (TRUE)
{
ATAReadBlks(bd, &mbr, offset, 1);
j =- 1;
for (i = 0; i < 4; i++)
{
cur_type = mbr.p[i].type;
if (cur_type)
{
if (cur_type == 5 || cur_type == 15)
j = i;
else
{
if (drv_num + 'A' == drv_let)
{
switch (type)
{
case FSt_REDSEA:
mbr.p[i].type=MBR_PT_REDSEA;
mbr.p[i].type = MBR_PT_REDSEA;
break;
case FSt_FAT32:
mbr.p[i].type=MBR_PT_FAT32a;
mbr.p[i].type = MBR_PT_FAT32a;
break;
default:
throw('Drive');
}
mbr.p[i].active=0x80;
ATAWriteBlks(bd,&mbr,offset,1);
mbr.p[i].active = 0x80;
ATAWriteBlks(bd, &mbr, offset, 1);
return TRUE;
}
drv_num++;
}
}
}
if (j<0)
if (j < 0)
break;
if (!mbr.p[j].offset)
break;
if (ext_base==INVALID_CLUS) {
offset=mbr.p[j].offset;
ext_base=offset;
} else
offset=mbr.p[j].offset+ext_base;
if (ext_base == INVALID_CLUS)
{
offset = mbr.p[j].offset;
ext_base = offset;
}
else
offset = mbr.p[j].offset+ext_base;
}
break;
}
}
U0 Format(I64 drv_let,Bool quick=TRUE,Bool confirm=TRUE,I64 type=FSt_FAT32)
U0 Format(I64 drv_let, Bool quick=TRUE, Bool confirm=TRUE, I64 type=FSt_FAT32)
{//Format hard drive or RAM drive.
//$BK,1$Warning:$BK,0$ Destroys all prev info.
//quick=FALSE means fill entire drive with zeros.
//Choose $LK,"FSt_FAT32",A="MN:FSt_FAT32"$ or $LK,"FSt_REDSEA",A="MN:FSt_REDSEA"$.
//You don't format a CD/DVD with this.
CDrive *drive=Letter2Drive(drv_let);
Bool old_silent=IsSilent;
CDrive *drive = Letter2Drive(drv_let);
Bool old_silent = IsSilent;
if (confirm && !AreYouSure)
return;
if (!drive) {
if (!drive)
{
PrintErr("Invalid Drive\n");
return;
}
switch (type) {
switch (type)
{
case FSt_FAT32:
if (drive->bd->type==BDT_ATA) {
if (drive->bd->type == BDT_ATA)
{
Silent;
Drive(drv_let);
Silent(old_silent);
FAT32Format(drv_let,quick);
FAT32Format(drv_let, quick);
DiskCacheInvalidate(Letter2Drive(drv_let));
Drive(drv_let);
break;
@ -82,7 +96,7 @@ U0 Format(I64 drv_let,Bool quick=TRUE,Bool confirm=TRUE,I64 type=FSt_FAT32)
Silent;
Drive(drv_let);
Silent(old_silent);
RedSeaFormat(drv_let,quick);
RedSeaFormat(drv_let, quick);
DiskCacheInvalidate(Letter2Drive(drv_let));
Drive(drv_let);
break;

View file

@ -1,28 +1,35 @@
U8 *FileExtDot(U8 *src)
{//Find dot char in name.
I64 ch;
while (ch=*src++)
if (ch=='.' && *src!='/' && *src!='.')
return src-1;
while (ch = *src++)
if (ch == '.' && *src != '/' && *src != '.')
return src - 1;
return NULL;
}
U8 *FileExtRemove(U8 *src,U8 *dst=NULL)
U8 *FileExtRemove(U8 *src, U8 *dst=NULL)
{//Remove filename extension from str.
U8 *ptr;
if (ptr=FileExtDot(src)) {
if (ptr = FileExtDot(src))
{
if (dst)
StrCopy(dst,ptr+1);
*ptr=0;
} else if (dst)
*dst=0;
StrCopy(dst, ptr + 1);
*ptr = 0;
}
else if (dst)
*dst = 0;
return dst;
}
Bool IsDotC(U8 *filename)
{//Does name end in .C?
I64 i=StrLen(filename);
if (StrOcc(filename,'.')>1 && filename[i-1]=='C' && filename[i-2]=='.')
I64 i = StrLen(filename);
if (StrOcc(filename, '.') > 1 && filename[i - 1] == 'C' && filename[i - 2] == '.')
return TRUE;
else
return FALSE;
@ -30,244 +37,284 @@ Bool IsDotC(U8 *filename)
Bool FilesFindMatch(U8 *_test_name,U8 *files_find_mask,I64 fuf_flags=0)
{//Does filename meet $LK,"Files Find",A="FI:::/Doc/FileUtils.DD"$ mask?
I64 tn_len=StrLen(_test_name),mask_len=StrLen(files_find_mask);
U8 *mask1=MAlloc(mask_len+1),*mask2=MAlloc(mask_len+1),
*ptr,*test_name1,*test_name2;
Bool res=FALSE;
I64 tn_len = StrLen(_test_name), mask_len = StrLen(files_find_mask);
U8 *mask1 = MAlloc(mask_len + 1), *mask2 = MAlloc(mask_len + 1), *ptr, *test_name1, *test_name2;
Bool res = FALSE;
StrCopy(mask1,files_find_mask);
if (StrOcc(_test_name,'/')) {
test_name1=MAlloc(tn_len+1);
test_name2=MAlloc(tn_len+1);
StrCopy(test_name1,_test_name);
StrLastRemove(test_name1,"/",test_name2);
} else {
test_name1=NULL;
test_name2=NULL;
if (StrOcc(_test_name, '/'))
{
test_name1 = MAlloc(tn_len + 1);
test_name2 = MAlloc(tn_len + 1);
StrCopy(test_name1, _test_name);
StrLastRemove(test_name1, "/", test_name2);
}
while (TRUE) {
StrFirstRemove(mask1,";",mask2);
if (!test_name2 || StrOcc(mask2,'/'))
ptr=_test_name;
else
{
test_name1 = NULL;
test_name2 = NULL;
}
while (TRUE)
{
StrFirstRemove(mask1, ";", mask2);
if (!test_name2 || StrOcc(mask2, '/'))
ptr = _test_name;
else
ptr=test_name2;
if (*mask2) {
if (*mask2=='!') {
if (WildMatch(ptr,mask2+1)) {
res=FALSE;
ptr = test_name2;
if (*mask2)
{
if (*mask2 == '!')
{
if (WildMatch(ptr, mask2 + 1))
{
res = FALSE;
break;
}
} else {
if (WildMatch(ptr,mask2)) {
if (Bt(&fuf_flags,FUf_JUST_TXT) &&
!FilesFindMatch(_test_name,FILEMASK_TXT)) {
}
else
{
if (WildMatch(ptr, mask2))
{
if (Bt(&fuf_flags, FUf_JUST_TXT) && !FilesFindMatch(_test_name, FILEMASK_TXT)) {
res=FALSE;
break;
} else if (Bt(&fuf_flags,FUf_JUST_DD) &&
!FilesFindMatch(_test_name,FILEMASK_DD)) {
} else if (Bt(&fuf_flags, FUf_JUST_DD) && !FilesFindMatch(_test_name, FILEMASK_DD)) {
res=FALSE;
break;
} else if (Bt(&fuf_flags,FUf_JUST_SRC) &&
!FilesFindMatch(_test_name,FILEMASK_SRC)) {
} else if (Bt(&fuf_flags, FUf_JUST_SRC) && !FilesFindMatch(_test_name, FILEMASK_SRC)) {
res=FALSE;
break;
} else if (Bt(&fuf_flags,FUf_JUST_AOT) &&
!FilesFindMatch(_test_name,FILEMASK_AOT)) {
} else if (Bt(&fuf_flags, FUf_JUST_AOT) && !FilesFindMatch(_test_name, FILEMASK_AOT)) {
res=FALSE;
break;
} else if (Bt(&fuf_flags,FUf_JUST_JIT) &&
!FilesFindMatch(_test_name,FILEMASK_JIT)) {
} else if (Bt(&fuf_flags, FUf_JUST_JIT) && !FilesFindMatch(_test_name, FILEMASK_JIT)) {
res=FALSE;
break;
} else if (Bt(&fuf_flags,FUf_JUST_GR) &&
!FilesFindMatch(_test_name,FILEMASK_GR)) {
} else if (Bt(&fuf_flags, FUf_JUST_GR) && !FilesFindMatch(_test_name, FILEMASK_GR)) {
res=FALSE;
break;
} else
res=TRUE;
}
}
} else
}
else
break;
}
Free(test_name1);
Free(test_name2);
Free(mask1);
Free(mask2);
return res;
}
U8 *DirNameAbs(U8 *_dirname)
{//MAlloc absolute dir string with drv letter.
I64 maxlen;
U8 drv[3],*res,*buf,*buf2,*buf3,*buf4,*dirname,*free_dirname;
U8 drv[3], *res, *buf, *buf2, *buf3, *buf4, *dirname, *free_dirname;
if (!Fs->cur_dir || !*Fs->cur_dir)
return StrNew(_dirname);
free_dirname=dirname=MStrUtil(_dirname,
SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
*drv=Drive2Letter;
drv[1]=':';
drv[2]=0;
if (*dirname && dirname[1]==':') {
if (*dirname==':')
*drv=blkdev.boot_drive_let;
else if (*dirname=='~')
*drv=*blkdev.home_dir;
free_dirname=dirname = MStrUtil(_dirname, SUF_REM_LEADING | SUF_REM_TRAILING | SUF_REM_CTRL_CHARS);
*drv = Drive2Letter;
drv[1] = ':';
drv[2] = 0;
if (*dirname && dirname[1] == ':')
{
if (*dirname == ':')
*drv = blkdev.boot_drive_let;
else if (*dirname == '~')
*drv = *blkdev.home_dir;
else
*drv=*dirname;
dirname=dirname+2;
buf=StrNew("/");
} else
buf=StrNew(Fs->cur_dir);
if (*dirname=='/') {
*drv = *dirname;
dirname = dirname + 2;
buf = StrNew("/");
}
else
buf = StrNew(Fs->cur_dir);
if (*dirname == '/')
{
Free(buf);
buf=StrNew("/");
buf = StrNew("/");
dirname++;
}
buf2=StrNew(dirname);
maxlen=StrLen(buf)+1+StrLen(buf2)+1;
buf3=MAlloc(maxlen);
buf4=MAlloc(maxlen);
StrCopy(buf3,buf);
while (*buf2) {
StrFirstRemove(buf2,"/",buf4);
buf2 = StrNew(dirname);
maxlen = StrLen(buf) + 1 + StrLen(buf2) + 1;
buf3 = MAlloc(maxlen);
buf4 = MAlloc(maxlen);
StrCopy(buf3, buf);
while (*buf2)
{
StrFirstRemove(buf2, "/", buf4);
if (!*buf4)
StrCopy(buf3,"/");
else if (!StrCompare(buf4,"..")) {
StrLastRemove(buf3,"/");
StrCopy(buf3, "/");
else if (!StrCompare(buf4, ".."))
{
StrLastRemove(buf3, "/");
if (!*buf3)
StrCopy(buf3,"/");
} else if (!StrCompare(buf4,"~")) {
StrCopy(buf3, "/");
}
else if (!StrCompare(buf4, "~"))
{
Free(buf3);
buf3=MAlloc(StrLen(blkdev.home_dir+2)+1+StrLen(buf2)+1);
StrCopy(buf3,blkdev.home_dir+2);
*drv=*blkdev.home_dir;
} else if (!StrCompare(buf4,"."));
else if (*buf4) {
if (StrCompare(buf3,"/"))
CatPrint(buf3,"/");
CatPrint(buf3,buf4);
buf3 = MAlloc(StrLen(blkdev.home_dir + 2) + 1 + StrLen(buf2) + 1);
StrCopy(buf3, blkdev.home_dir + 2);
*drv = *blkdev.home_dir;
}
else if (!StrCompare(buf4, "."));
else if (*buf4)
{
if (StrCompare(buf3, "/"))
CatPrint(buf3, "/");
CatPrint(buf3, buf4);
}
}
Free(buf);
res=MAlloc(StrLen(buf3)+3);
StrCopy(res,drv);
StrCopy(res+2,buf3);
res = MAlloc(StrLen(buf3) + 3);
StrCopy(res, drv);
StrCopy(res + 2, buf3);
Free(buf2);
Free(buf3);
Free(buf4);
Free(free_dirname);
return res;
}
U8 *FileNameAbs(U8 *_filename,I64 fuf_flags=NONE)
U8 *FileNameAbs(U8 *_filename, I64 fuf_flags=NONE)
{//Absolute filename. Accepts $LK,"FUF_SCAN_PARENTS",A="MN:FUF_SCAN_PARENTS"$.
U8 *res,*filename,*buf,*buf_file,*buf_dir,*free_filename,*free_buf;
CDirEntry de;
free_filename=filename=MStrUtil(_filename,
SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
free_buf=buf=StrNew(filename);
if (*buf && buf[1]==':') {
buf+=2;
filename+=2;
U8 *res, *filename, *buf, *buf_file, *buf_dir, *free_filename, *free_buf;
CDirEntry de;
free_filename = filename = MStrUtil(_filename, SUF_REM_LEADING | SUF_REM_TRAILING | SUF_REM_CTRL_CHARS);
free_buf = buf = StrNew(filename);
if (*buf && buf[1] == ':')
{
buf += 2;
filename += 2;
}
buf_file=MAlloc(StrLen(free_filename)+1);
StrLastRemove(buf,"/",buf_file);
if (*filename=='/' && !*buf)
StrCopy(buf,"/");
buf_dir=DirNameAbs(free_buf);
buf_file = MAlloc(StrLen(free_filename) + 1);
StrLastRemove(buf, "/", buf_file);
if (*filename == '/' && !*buf)
StrCopy(buf, "/");
buf_dir = DirNameAbs(free_buf);
Free(free_buf);
res=MAlloc(StrLen(buf_dir)+1+StrLen(buf_file)+1);
StrCopy(res,buf_dir);
if (res[StrLen(res)-1]!='/')
CatPrint(res,"/");
CatPrint(res,buf_file);
res = MAlloc(StrLen(buf_dir) + 1 + StrLen(buf_file) + 1);
StrCopy(res, buf_dir);
if (res[StrLen(res) - 1] != '/')
CatPrint(res, "/");
CatPrint(res, buf_file);
Free(buf_file);
Free(buf_dir);
Free(free_filename);
if (fuf_flags && FileFind(res,&de,fuf_flags|FUF_JUST_FILES)) {
if (fuf_flags && FileFind(res, &de, fuf_flags | FUF_JUST_FILES))
{
Free(res);
res=de.full_name;
res = de.full_name;
}
return res;
}
U8 *ExtChange(U8 *filename,U8 *extension)
U8 *ExtChange(U8 *filename, U8 *extension)
{//Change filename extension.
U8 *res=MAlloc(StrLen(filename)+1+StrLen(extension)+1);
StrCopy(res,filename);
U8 *res = MAlloc(StrLen(filename) + 1 + StrLen(extension) + 1);
StrCopy(res, filename);
if (FileExtDot(filename))
FileExtRemove(res);
return CatPrint(res,".%s",extension);
return CatPrint(res, ".%s", extension);
}
U8 *ExtDefault(U8 *filename,U8 *extension)
U8 *ExtDefault(U8 *filename, U8 *extension)
{//Give extension if has none.
U8 *res=MAlloc(StrLen(filename)+1+StrLen(extension)+1);
StrCopy(res,filename);
U8 *res = MAlloc(StrLen(filename) + 1 + StrLen(extension) + 1);
StrCopy(res, filename);
if (!FileExtDot(filename))
CatPrint(res,".%s",extension);
CatPrint(res, ".%s", extension);
return res;
}
CDirEntry *Cd2DirEntry(CDirEntry *tmpde,U8 *abs_name)
CDirEntry *Cd2DirEntry(CDirEntry *tmpde, U8 *abs_name)
{
I64 i;
while (tmpde) {
i=StrLen(tmpde->full_name);
if (StrNCompare(tmpde->full_name,abs_name,i)||
i && tmpde->full_name[i-1]!='/' && abs_name[i] && abs_name[i]!='/')
tmpde=tmpde->next;
while (tmpde)
{
i = StrLen(tmpde->full_name);
if (StrNCompare(tmpde->full_name, abs_name, i) ||
i && tmpde->full_name[i - 1] != '/' &&
abs_name[i] &&
abs_name[i] != '/')
tmpde = tmpde->next;
else
if (StrLen(abs_name)==i)
if (StrLen(abs_name) == i)
return tmpde;
else
return Cd2DirEntry(tmpde->sub,abs_name);
return Cd2DirEntry(tmpde->sub, abs_name);
}
return NULL;
}
I64 FileAttr(U8 *name,I64 attr=0)
I64 FileAttr(U8 *name, I64 attr=0)
{
if (IsDotC(name))
attr|=RS_ATTR_CONTIGUOUS;
attr |= RS_ATTR_CONTIGUOUS;
return attr;
}
Bool FileNameCheck(U8 *filename)
{//Return check for valid filename, not checking existence.
U8 *ptr=filename;
if (!filename) return FALSE;
if (!*ptr) return FALSE;
if (*ptr=='.') {
if (!ptr[1]) return TRUE;
if (ptr[1]=='.' && !ptr[2]) return TRUE;
U8 *ptr = filename;
if (!filename)
return FALSE;
if (!*ptr)
return FALSE;
if (*ptr == '.')
{
if (!ptr[1])
return TRUE;
if (ptr[1] == '.' && !ptr[2])
return TRUE;
}
if (StrLen(filename)>=CDIR_FILENAME_LEN) return FALSE;
if (StrLen(filename) >= CDIR_FILENAME_LEN)
return FALSE;
while (*ptr)
if (!Bt(char_bmp_filename,*ptr++))
if (!Bt(char_bmp_filename, *ptr++))
return FALSE;
return TRUE;
}
U8 *FileNameTmpTxt()
{//Make pretty-safe tmp filename in home dir.
return MStrPrint("~/SysTmp%X.DD",TSCGet>>8&0xFFFFFFFF);
return MStrPrint("~/SysTmp%X.DD", TSCGet >> 8 & 0xFFFFFFFF);
}
U8 *DirCur(CTask *task=NULL,CTask *mem_task=NULL)
U8 *DirCur(CTask *task=NULL, CTask *mem_task=NULL)
{//MAlloc copy of cur dir with drv letter.
U8 *st;
if (!task) task=Fs;
if (!task)
task = Fs;
if (!task->cur_dir)
return NULL;
st=MAlloc(StrLen(task->cur_dir)+3,mem_task);
*st=Drive2Letter(task->cur_dv);
st[1]=':';
StrCopy(st+2,task->cur_dir);
st = MAlloc(StrLen(task->cur_dir) + 3, mem_task);
*st = Drive2Letter(task->cur_dv);
st[1] = ':';
StrCopy(st + 2, task->cur_dir);
return st;
}
U8 *DirFile(U8 *dirname,U8 *name=NULL,U8 *_extension=NULL)
U8 *DirFile(U8 *dirname, U8 *name=NULL, U8 *_extension=NULL)
{/*Strips file from dirname, scans for file upward until found or
returns default.
@ -276,32 +323,38 @@ returns default.
("/Kernel/BlkDev",NULL,"PRJ") returns "D:/Kernel/Kernel.PRJ"
("/Apps/Psalmody","Load","HC") returns "D:/Apps/Psalmody/Load.CC"
*/
U8 *st=DirNameAbs(dirname),*st2,*st3,*res,*default=NULL,*ext;
if (_extension && *_extension) {
if (*_extension=='.')
ext=StrNew(_extension);
U8 *st = DirNameAbs(dirname), *st2, *st3, *res, *default = NULL, *ext;
if (_extension && *_extension)
{
if (*_extension == '.')
ext = StrNew(_extension);
else
ext=MStrPrint(".%s",_extension);
} else
ext=StrNew("");
while (StrOcc(st,'/')&&!IsDir(st))
StrLastRemove(st,"/");
while (StrOcc(st,'/')) {
st2=StrNew(st);
st3=StrNew(st);
StrLastRemove(st2,"/",st3);
ext = MStrPrint(".%s", _extension);
}
else
ext = StrNew("");
while (StrOcc(st, '/') && !IsDir(st))
StrLastRemove(st, "/");
while (StrOcc(st, '/'))
{
st2 = StrNew(st);
st3 = StrNew(st);
StrLastRemove(st2, "/", st3);
if (name)
res=MStrPrint("%s/%s%s",st,name,ext);
else {
res = MStrPrint("%s/%s%s", st, name, ext);
else
{
if (*ext)
res=MStrPrint("%s/%s%s",st,st3,ext);
res = MStrPrint("%s/%s%s", st, st3, ext);
else
res=StrNew(st);
res = StrNew(st);
}
if (!default)
default=StrNew(res);
if (!*ext && (!name||!*name) || FileFind(res)) {
default = StrNew(res);
if (!*ext && (!name || !*name) || FileFind(res))
{
Free(st3);
Free(st2);
Free(st);
@ -310,10 +363,11 @@ returns default.
return res;
}
Free(st);
st=st2;
st = st2;
Free(st3);
}
Free(st);
Free(ext);
return default;
}

View file

@ -1,89 +1,106 @@
Bool CFileNameTo(U8 *dst,U8 *src)
Bool CFileNameTo(U8 *dst, U8 *src)
{
MemSet(dst,0,CDIR_FILENAME_LEN);
MemSet(dst, 0, CDIR_FILENAME_LEN);
if (!FileNameCheck(src))
return FALSE;
StrCopy(dst,src);
StrCopy(dst, src);
return TRUE;
}
I64 Name2DirClus(CDrive *drive,U8 *dirname)
I64 Name2DirClus(CDrive *drive, U8 *dirname)
{
Bool cont=TRUE,unlock;
I64 cur_dir_clus;
CDirEntry de;
U8 *buf=StrNew(dirname),*buf2=StrNew(dirname);
Bool cont = TRUE, unlock;
I64 cur_dir_clus;
CDirEntry de;
U8 *buf = StrNew(dirname), *buf2 = StrNew(dirname);
DriveCheck(drive);
try {
unlock=DriveLock(drive);
cur_dir_clus=drive->root_clus;
while (*buf && cont) {
StrFirstRemove(buf,"/",buf2);
if (*buf2) {
switch (drive->fs_type) {
try
{
unlock = DriveLock(drive);
cur_dir_clus = drive->root_clus;
while (*buf && cont)
{
StrFirstRemove(buf, "/", buf2);
if (*buf2)
{
switch (drive->fs_type)
{
case FSt_REDSEA:
cont=RedSeaFileFind(drive,cur_dir_clus,buf2,&de,FUF_JUST_DIRS);
cont = RedSeaFileFind(drive, cur_dir_clus, buf2, &de, FUF_JUST_DIRS);
break;
case FSt_FAT32:
cont=FAT32FileFind(drive,cur_dir_clus,buf2,&de,FUF_JUST_DIRS);
cont = FAT32FileFind(drive, cur_dir_clus, buf2, &de, FUF_JUST_DIRS);
break;
default:
throw('Drive');
}
cur_dir_clus=de.clus;
cur_dir_clus = de.clus;
}
}
if (!cont) {
PrintErr("File not found: \"%s\".\n",dirname);
cur_dir_clus=0;
if (!cont)
{
PrintErr("File not found: \"%s\".\n", dirname);
cur_dir_clus = 0;
}
if (unlock)
DriveUnlock(drive);
} catch
}
catch
if (unlock)
DriveUnlock(drive);
Free(buf);
Free(buf2);
return cur_dir_clus;
}
I64 Name2ParentDirClus(CDrive *drive,U8 *dirname)
I64 Name2ParentDirClus(CDrive *drive, U8 *dirname)
{
Bool cont=TRUE,unlock;
I64 cur_dir_clus,cur_dir_clus2;
CDirEntry de;
U8 *buf=StrNew(dirname),*buf2=StrNew(dirname);
Bool cont = TRUE, unlock;
I64 cur_dir_clus, cur_dir_clus2;
CDirEntry de;
U8 *buf = StrNew(dirname), *buf2 = StrNew(dirname);
DriveCheck(drive);
try {
unlock=DriveLock(drive);
cur_dir_clus=cur_dir_clus2=drive->root_clus;
while (*buf && cont) {
cur_dir_clus2=cur_dir_clus;
StrFirstRemove(buf,"/",buf2);
if (*buf2) {
switch (drive->fs_type) {
try
{
unlock = DriveLock(drive);
cur_dir_clus = cur_dir_clus2 = drive->root_clus;
while (*buf && cont)
{
cur_dir_clus2 = cur_dir_clus;
StrFirstRemove(buf, "/", buf2);
if (*buf2)
{
switch (drive->fs_type)
{
case FSt_REDSEA:
cont=RedSeaFileFind(drive,cur_dir_clus,buf2,&de,FUF_JUST_DIRS);
cont = RedSeaFileFind(drive, cur_dir_clus, buf2, &de, FUF_JUST_DIRS);
break;
case FSt_FAT32:
cont=FAT32FileFind(drive,cur_dir_clus,buf2,&de,FUF_JUST_DIRS);
cont = FAT32FileFind(drive, cur_dir_clus, buf2, &de, FUF_JUST_DIRS);
break;
default:
throw('Drive');
}
cur_dir_clus=de.clus;
cur_dir_clus = de.clus;
}
}
if (!cont) {
PrintErr("File not found: \"%s\".\n",dirname);
if (!cont)
{
PrintErr("File not found: \"%s\".\n", dirname);
cur_dir_clus2=0;
}
if (unlock)
DriveUnlock(drive);
} catch
}
catch
if (unlock)
DriveUnlock(drive);
Free(buf);
Free(buf2);
return cur_dir_clus2;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff