mirror of
https://github.com/Zeal-Operating-System/ZealOS.git
synced 2025-04-18 05:38:36 +01:00
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:
parent
d9ac154e76
commit
ec3aa83b55
23 changed files with 2639 additions and 2043 deletions
Binary file not shown.
|
@ -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$
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue