📄 filesys.c
字号:
Function: Reads ICB for physical LSN(location) and size of "file" entry. input: icb_at: LSN of ICB info. output: 0: success -1: failed getSectors() start: holds start LSN of entry, if success size: holds size (in bytes) of entry, if success*************************************************************************/static int UDF_read_ICB(int icb_at, int *start, int *size){ int l_fi; uchar *pcbuf = (uchar *)dram_cached(ABV_start); *start = *size = 0; icb_at = logical2physical(icb_at+150); /* LSN to MSF */ /* getSectors data to ABV */ if(getSectors(icb_at, 1, 0) < 1) return -1; l_fi = get_bigend32(pcbuf, 168); l_fi += 180; *start = get_bigend32(pcbuf, l_fi) + partition_start; *size = get_bigend32(pcbuf, 56); return 0;}/* Function: Used as "scan function" in scan_getnsector(). Parses getSectors() buffer for "main_start" and "partition_start" info. input: sectors: number of sectors to scan. cptr: NOT USED output: -1: "Terminator" found..quit. 0: failed to find both main & partition starts. 1: if successful last_val: holds last value of "found". Used to determine if necessary info has been found.*/static int UDF_find_partition(int sectors, uchar *cptr, int *last_val){ int i, found; uchar *c_buf = (uchar *)dram_cached(GETSECTOR_DATA_START); found = *last_val; for (i=0; i<sectors; i++) { if (*c_buf == 6) { main_start = get_bigend32(c_buf, 252); CPRINTF("LOGICAL VOLUME DESC", main_start); found |= 0x1; } else if (*c_buf == 8) { /* Terminate */ return (-1); } else if (*c_buf == 5) { /* Partition..BP = 188 */ partition_start = get_bigend32(c_buf, 188); found |= 0x2; }#if 0 else if (*c_buf == 7) {/* Unallocated Space Descriptor */} else if (*c_buf == 4) {/* Implematation */} else if (*c_buf == 1) {/* Primary Volume Descriptor */}#endif if (!((found & 0x3) ^ 0x3)) { CPRINTF("FOUND MAIN N PART",0); return 1; } c_buf += 2048; } *last_val=found; return 0;}/* Function: Used as "scan function" in scan_getnsector(). Parses getSectors() buffer for UDF identifiers. input: sectors: number of sectors to scan. cptr: NOT USED output: 0: failed to find any UDF IDs. 1: if successful last_val: holds last value of "valid_udf". Used to determine if necessary info has been found.*/static int UDF_validate(int sectors, uchar *cptr, int *last_val){ int i, valid_udf; uchar *c_buf = (uchar *)dram_cached(GETSECTOR_DATA_START); valid_udf = *last_val; for ( i=0; i < sectors; i++) { if (strncmp(c_buf+1, "NSR02", 5) == 0) { valid_udf |= 0x1; CPRINTF("NSR",0); } else if(strncmp(c_buf+1, "BEA01", 5) == 0) { valid_udf |= 0x2; CPRINTF("BEGIN",0); } else if(strncmp(c_buf+1, "TEA01", 5) == 0) { valid_udf |= 0x4; CPRINTF("TERMINATE",0); } if (valid_udf & 0x7) { CPRINTF("VALID UDF",0); return 1; } c_buf += 2048; } *last_val=valid_udf; return 0;}/* Function: Finds the Root location and size. input: output: -1: failed getSectors(). 0: Invalid Root info. >0: if success. ROOT_loc: Holds root location (MSF) if successful. ROOT_size: Holds root size (in sectors) if successful.*/static int UDF_find_root(void){ uchar *c_buf = (uchar *)dram_cached(GETSECTOR_DATA_START); int sec; CPRINTF("UDF SCAN ROOT",0); /* UDF confirmation: * Volume Recognition Sequence Schema */ partition_start = 0; if (!scan_getnsector(0x216, 10, NULL, UDF_validate)) return (-1); fs_type = UDF_FS; CPRINTF("READING ANCHOR",0); /* Anchor point..Fixed address*/ if (getSectors(0x531, 1, 2048) < 1) { CPRINTF("FAILED GETSECTOR 2",0); return (-1); } sec = get_bigend32(c_buf, 20); sec = logical2physical(sec+150); /* LSN to MSF */ CPRINTF("FINDING PARTITION", sec); if (!scan_getnsector(sec, 10, NULL, UDF_find_partition)) return (-1); main_start += partition_start; CPRINTF("FILESET DESCRIPTOR", main_start); main_start = logical2physical(main_start+150); /* LSN to MSF */ /* File Set Descriptor */ if (getSectors(main_start, 1, 2048) < 1) return -1; if ((c_buf[0] != 0x00) || (c_buf[1] != 0x01)) return (0); main_start = get_bigend32(c_buf, 404) + partition_start; CPRINTF("ROOT ICB", main_start); UDF_read_ICB(main_start, &ROOT_loc, &ROOT_size); ROOT_loc = logical2physical(ROOT_loc+150); ROOT_size = (ROOT_size+2047)>>11; /* Sectors */ return (ROOT_size);}/* Function: Attempts to read the file system as UDF. input: output: -3: no valid files found (i.e. mp3). -2: failed other directories scan. -1: failed Root directory scan. 0: failed finding Root. 1: if success.*/static int UDF_read(void) { int file_cnt, ret, dir_cnt; CPRINTF("UDF READ",0); if (UDF_find_root() <= 0) return 0; CPRINTF("UDF FOUND ROOT", ROOT_loc); if (read_iso9660_dir()) return (-1); CPRINTF("SCANNING DIRS", 0); if(read_iso9660_files()) return (-2); CPRINTF("DIRS SCAN DONE", 0); #ifdef DATA_CD if (iso9660_file_cnt){ CDinfo.lasttrack = iso9660_file_cnt; CDinfo.firsttrack = 1; mp3_total_page = (real_track_cnt-1)/ItemNum; num_of_track = iso9660_file_cnt; mp3_menu_changed = 1; return 1; }#endif return (-3);}#endif UDF#ifdef JPEG_DECstatic int is_FUJI_cd(int size){ int i; char *root_p; root_p = (char *)dram(VBV_start); size = size*2048; for(i=0; i<(size-10); i++, root_p += 1) { if( !strncmp(root_p, "COMMON", 6 ) ) is_fuji_cd |= 0x80; else if( !strncmp(root_p, "DCIM", 4) ) is_fuji_cd |= 0x40; else if( !strncmp(root_p, "LOCAL", 5) ) is_fuji_cd |= 0x20; else if(!strncmp(root_p, "IMAGE.DEF", 9) ) is_fuji_cd |= 0x2; else if( !strncmp(root_p, "IMAGE.INF", 9) ) is_fuji_cd |= 0x1; }}#endif /*JPEG_DEC*/#ifdef MULTI_EXT_FILEint ISO_multi_ext_end(void){ struct DIR_REC *fs_rec_ptr = &iso9660_file[cur_file_rec+1]; /* check next file record for multi-extent */ if (fs_rec_ptr->dir & 0xff00) { if(av_play_continue((fs_rec_ptr->loc & x00ffffff), fs_rec_ptr->size)) { /* av_play_continue(): * - NO system_reset() to avoid audio-breaks! * - clears end_of_play * - loads XPORT new start/end * - prepare video_state_machine */ cur_file_rec++; /* play next file record */ return(0); } } return (1);}/* gets file-record index from file/track number */int track_to_rec(int track){ int i=0, trk=0; while (trk < track) { if (!(iso9660_file[i++].dir & 0xff00)) trk++; } return(i-1); /* return index into iso9660_file[] */}#endif /* MULTI_EXT_FILE *//************************************************************************ Function: Checks filename contains one of the supported suffixes. input: name - zero-terminated string to be checked. output: id - specific ID flags if supported. 0(zero) - if suffix didn't matched. NOTE: add new suffixes to suffix_filter[] when needed.*************************************************************************/static uchar FS_filter_filename(unsigned char *name, int len){ int i, count; count = sizeof(suffix_filter)/sizeof(SUF_ID); for (i = 0; i < count; i++) { if (iso_search_str(name, suffix_filter[i].suf, len, NULL)) { return (suffix_filter[i].id); /* suffix match..return ID */ } } return (0); /* no match */}#ifdef ABNORMAL_VCD/* input: dir_index - directory index. 0 for root. output: (last_record[7:4]|target_found[3:0]) target_found - 0: no target found. 1: found target file 2: found target directory 3: found target file and directory last_record - 1: indicates last record found.*/ static int search_dir_file(uchar *target_dir, uchar *target_file, int size, int dir_index){ struct iso_directory_record *pdir; char *curBuf, *nxtBuf; char *begBuf, *endBuf; int namelen; unsigned int flags, reclen; int loc, sz, bsz, temp; int target_found = 0; int last_record = 0; int search_cnt = 0; uchar filename[MAX_JOLIET_STRING+1]; begBuf = nxtBuf = (char *)dram(GETSECTOR_DATA_START); endBuf = begBuf + (size<<11); do{ curBuf = nxtBuf; /* Sanity check for "iso_directory_record" */ if(bad_iso_directory_record(curBuf)) { CPRINTF("FIX DIR", iso9660_dir[dir_index].loc); nxtBuf = curBuf + 1; if (nxtBuf>=endBuf) break; /* reached end of current buffer */ if (search_cnt++ > 0xff) { /* rec_len max */ last_record = 0x10; /* quit */ break; } else continue; } search_cnt = 0; pdir = (struct iso_directory_record *)curBuf; reclen = pdir->length[0]; /* < 256 (8bits data) */ loc = get_litend32(pdir->extent, 4); sz = get_litend32(pdir->size, 4); flags = *pdir->flags; nxtBuf = curBuf + reclen; if (loc<=0) { CPRINTF("INVALID LOC", loc); continue;/* impossible..but don't quit */ } else { loc = logical2physical(loc + 150); /* LBA to MSF */ if (loc == xMAX_CDTIME) continue; } namelen = *pdir->name_len; if ((namelen==1) && ((pdir->name[0] == 0) || (pdir->name[0] == 1))) continue; /* skip . */ if (namelen > MAX_JOLIET_STRING) namelen = MAX_JOLIET_STRING; /* clear buffer */ memcpy(filename, (uchar *)dram(PCM_zero_start), MAX_JOLIET_STRING); FS_process_name(pdir->name, filename, namelen, sec_vol_table); if (sec_vol_table) namelen >>= 1; CPRINTF(filename, 0); bsz = sz; /* Bytes */ /* add 2047 to avoid truncation from bytes to sectors conversion * NOTE: for ID3 tag info, should dump the last 2 sectors of MP3 * file! */ sz = (sz + 2047) >> 11; /* Sectors */ if (flags & 0x2){ /* directory */ if (iso9660_dir_cnt < MAX_DIR_CNT) { if (strncmp(filename, target_dir, 8)) { /* only care about "target" directory */ continue; } iso9660_dir[iso9660_dir_cnt].loc = loc; iso9660_dir[iso9660_dir_cnt].size = sz;#if NOT_USED /* enable if needed later */ iso9660_dir[iso9660_dir_cnt].dir = -1; /* it is dir */ iso9660_assign_name(filename, iso9660_dir[iso9660_dir_cnt].name, iso9660_dir_cnt|0x8000, namelen);#endif iso9660_dir_cnt++; target_found |= 2; /* found directory */ } } else if (iso9660_file_cnt < MAX_FILE_CNT) { /* for suffix matching, only need to specify upper-case patterns. NOTE: add new suffixes to suffix_filter[] when needed. */ if (strncmp(filename, target_file, 8)) { /* only care about "target" file */ continue; } iso9660_file[iso9660_file_cnt].loc = loc;#if NOT_USED /* enable if needed later */ iso9660_file[iso9660_file_cnt].size = sz; /* parent dir */ iso9660_file[iso9660_file_cnt].dir = dir_index; iso9660_assign_name(filename, iso9660_file[iso9660_file_cnt].name, iso9660_file_cnt - dir_file_cnt, namelen); #endif iso9660_file_cnt++; /* file records */ real_track[real_track_cnt] = dir_index; target_found |= 1; } } while (1); return(last_record | target_found);}#endif /* ABNORMAL_VCD */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -