CDirEntry *FilesFind2(U8 *files_find_mask, I64 fuf_flags)
{
    CDrive      *drive = Fs->cur_dv;
    CDirEntry   *res   = NULL;

    DriveCheck(drive);
    switch (drive->fs_type)
    {
        case FSt_REDSEA:
            res = RedSeaFilesFind(files_find_mask, fuf_flags);
            break;

        case FSt_FAT32:
            res = FAT32FilesFind(files_find_mask, fuf_flags);
            break;

        case FSt_ISO9660:
            res = ISOFilesFind(files_find_mask, fuf_flags);
            break;

        default:
            PrintErr("File System Not Supported\n");
            res = NULL;
    }
    if (res)
    {
        DirFilesSort(&res, SK_NAME);
        if (fuf_flags & (FUF_FLATTEN_TREE | FUF_JUST_FILES))
            DirFilesFlatten(res, &res, fuf_flags);
        if (fuf_flags & FUF_CLUS_ORDER)
            DirFilesSort(&res, SK_CLUS);
    }
    return res;
}

CDirEntry *FilesFind(U8 *files_find_mask, I64 fuf_flags=0)
{/* See ::/Doc/FileUtils.DD.

Find files and make a directory tree in memory.

When done,  you free with DirEntryDel(), DirEntryDel2(), 
DirTreeDel() or DirTreeDel2().

*/
    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))
        {
            Free(res);
            return NULL;
        }
    }
    else if (dirc = DirContextNew(files_find_mask, TRUE))
    {
        res = FilesFind2(dirc->mask, fuf_flags);
        DirContextDel(dirc);
    }
    else
        return NULL;
    return res;
}

Bool FileFind(U8 *filename, CDirEntry *_de=NULL, I64 fuf_flags=0)
{//FUF_JUST_DIRS,  FUF_JUST_FILES, 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)
        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);
        switch (dirc->drive->fs_type)
        {
            case FSt_REDSEA:
                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);
                break;

            case FSt_ISO9660:
                res = ISOFileFind(dirc->drive, cur_dir_clus, dirc->mask, &de, fuf_flags);
                break;

            default:
                PrintErr("File System Not Supported\n");
        }
        if (res && _de)
        {
            if (StrCompare(Fs->cur_dir, "/"))
                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);
        }
        DirContextDel(dirc);
    }
    if (!res && fuf_flags & FUF_SCAN_PARENTS)
    {
        if (dirc = DirContextNew(filename))
        {
            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)
                {
                    case FSt_REDSEA:
                        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);
                        break;

                    case FSt_ISO9660:
                        res = ISOFileFind(dirc->drive, cur_dir_clus, dirc->mask, &de, fuf_flags);
                        break;

                    default:
                        PrintErr("File System Not Supported\n");
                }
            }
            if (res && _de)
            {
                if (StrCompare(Fs->cur_dir, "/"))
                    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);
            }
            DirContextDel(dirc);
        }
    }
    if (_de)
    {
        if (res)
        {
            MemCopy(_de, &de, sizeof(CDirEntry));
            _de->full_name = full_name;
        }
        else
            MemSet(_de, 0, sizeof(CDirEntry));
    }
    return res;
}