U0 Date2ISO(CISODate *dst, CDate cdt) { CDateStruct ds; Date2Struct(&ds, cdt); dst->year = ds.year - ISO_BASE_YEAR; dst->mon = ds.mon; dst->day = ds.day_of_mon; dst->hour = ds.hour; dst->min = ds.min; dst->sec = ds.sec; dst->sec100 = ds.sec100; } CDate ISODateStruct2CDate(CISODate *dt) { CDateStruct ds; MemSet(&ds, 0, sizeof(CDateStruct)); ds.day_of_mon = dt->day; ds.mon = dt->mon; ds.year = dt->year + ISO_BASE_YEAR; ds.sec100 = dt->sec100; ds.sec = dt->sec; ds.min = dt->min; ds.hour = dt->hour; return Struct2Date(&ds); } Bool ISOFromName(U8 *dst, U8 *src) { I64 i, j, n; MemSet(dst, 0, CDIR_FILENAME_LEN); n = *src++; if (n == 1 && ! *src) { *dst = '.'; } else if (n == 1 && *src == 1) { *dst = '.'; dst[1] = '.'; } else { n >>= 1; j = 0; for (i = 0; i < n; i++) { src++; if (*src == ';') break; if (Bt(char_bmp_filename, *src)) { if (j >= CDIR_FILENAME_LEN - 1) return FALSE; dst[j++] = *src++; } else return FALSE; } } return FileNameCheck(dst); } Bool ISOCDirFill(CDirEntry *tmpde, CISODirEntry *de) { Bool res; MemSet(tmpde, 0, sizeof(CDirEntry)); res = ISOFromName(tmpde->name, &de->name_len); tmpde->clus = de->loc.little; tmpde->size = de->size.little; tmpde->attr = FileAttr(tmpde->name); if (de->flags & ISO_ATTR_DIR) tmpde->attr |= RS_ATTR_DIR; tmpde->datetime = ISODateStruct2CDate(&de->date); return res; } Bool ISOFileFind(CDrive *drive, I64 cur_dir_clus, U8 *name, CDirEntry *_res, I64 fuf_flags = 0) { //FUF_JUST_DIRS, FUF_JUST_FILES CISODirEntry *isoptr, *buf; U8 dname[CDIR_FILENAME_LEN]; Bool res = FALSE, unlock; I64 i; if (fuf_flags & ~FUG_FILE_FIND) throw ('FUF'); DriveCheck(drive); if (drive->fs_type != FSt_ISO9660) PrintErr("Not ISO9660 Drive\n"); else try { unlock = DriveLock(drive); isoptr = MAlloc(drive->spc << BLK_SIZE_BITS); ClusRead(drive, isoptr, cur_dir_clus, 1); if (isoptr->name_len == 1 && !isoptr->name) { //curdir i = (isoptr->size.little + drive->spc << BLK_SIZE_BITS - 1) / drive->spc << BLK_SIZE_BITS; buf = MAlloc(drive->spc << BLK_SIZE_BITS * i); ClusRead(drive, buf, cur_dir_clus, i); Free(isoptr); } else { buf = isoptr; i = 1; } i *= drive->spc << BLK_SIZE_BITS; isoptr = buf; while (i > 0) { if (!isoptr->len) { isoptr(U8 *)++; i--; } else { ISOFromName(dname, &isoptr->name_len); if (*dname) { if (!StrCompare(name, dname)) { res = ISOCDirFill(_res, isoptr); if (res && !(fuf_flags & FUF_JUST_DIRS && !(_res->attr & RS_ATTR_DIR)) && !(fuf_flags & FUF_JUST_FILES && _res->attr & RS_ATTR_DIR)) goto iff_done; else res = FALSE; } } i -= isoptr->len; isoptr(U8 *) += isoptr->len; } } iff_done: Free(buf); if (unlock) DriveUnlock(drive); } catch if (unlock) DriveUnlock(drive); return res; } U8 *ISOFileRead(CDrive *drive, U8 *cur_dir, U8 *filename, I64 *_size, I64 *_attr) { U8 *buf = NULL; CDirEntry de; I64 c, blk_cnt, cur_dir_clus; DriveCheck(drive); *_size = 0; *_attr = 0; if (drive->fs_type != FSt_ISO9660) PrintErr("Not ISO9660 Drive\n"); else try { DriveLock(drive); cur_dir_clus = Name2DirClus(drive, cur_dir); if (ISOFileFind(drive, cur_dir_clus, filename, &de, FUF_JUST_FILES)) { blk_cnt = (de.size + BLK_SIZE - 1) >> BLK_SIZE_BITS; buf = MAlloc(blk_cnt << BLK_SIZE_BITS + 1); c = de.clus; c = ClusBlkRead(drive, buf, c, blk_cnt); buf[de.size] = 0; //Terminate *_size = de.size; *_attr = FileAttr(de.name, de.attr); } DriveUnlock(drive); } catch DriveUnlock(drive); return buf; } Bool ISOCd(U8 *name, I64 cur_dir_clus) { CDirEntry de; if (Fs->cur_dv->fs_type != FSt_ISO9660) PrintErr("Not ISO9660 Drive\n"); else if (ISOFileFind(Fs->cur_dv, cur_dir_clus, name, &de, FUF_JUST_DIRS)) return TRUE; else PrintErr("File not found: \"%s\".\n", name); return FALSE; } CDirEntry *ISOFilesFind(U8 *files_find_mask, I64 fuf_flags, CDirEntry *parent = NULL) { CDrive *drive = Fs->cur_dv; CISODirEntry *buf, *buf2, *isoptr; I64 i, cur_dir_clus = Name2DirClus(drive, Fs->cur_dir); CDirEntry *res = NULL, *tmpde; if (fuf_flags & ~FUG_FILES_FIND) throw ('FUF'); isoptr = MAlloc(drive->spc << BLK_SIZE_BITS); ClusRead(drive, isoptr, cur_dir_clus, 1); if (isoptr->name_len == 1 && !isoptr->name) { //curdir i = (isoptr->size.little + drive->spc << BLK_SIZE_BITS - 1) / drive->spc << BLK_SIZE_BITS; buf = MAlloc(drive->spc << BLK_SIZE_BITS * i); ClusRead(drive, buf, cur_dir_clus, i); Free(isoptr); } else { buf = isoptr; i = 1; } buf2 = buf; i *= drive->spc << BLK_SIZE_BITS; while (i > 0) { if (!buf->len) { buf(U8 *) ++; i--; } else { tmpde = MAlloc(sizeof(CDirEntry)); if (ISOCDirFill(tmpde, buf)) { tmpde->parent = parent; if (Bt(&fuf_flags, FUf_RECURSE) && tmpde->attr & RS_ATTR_DIR && *tmpde->name != '.') { tmpde->next = res; res = tmpde; tmpde->full_name = DirNameAbs(tmpde->name); if (Cd(tmpde->name)) { tmpde->sub = ISOFilesFind(files_find_mask, fuf_flags, tmpde); Cd(".."); } } else { tmpde->full_name = FileNameAbs(tmpde->name); if ((tmpde->attr & RS_ATTR_DIR || !Bt(&fuf_flags, FUf_JUST_DIRS)) && !(Bt(&fuf_flags, FUf_RECURSE) && *tmpde->name == '.' && tmpde->attr & RS_ATTR_DIR) && FilesFindMatch(tmpde->full_name, files_find_mask, fuf_flags)) { tmpde->next = res; res = tmpde; } else DirEntryDel(tmpde); } } else DirEntryDel(tmpde); i -= buf->len; buf(U8 *) += buf->len; } } Free(buf2); return res; }