📄 filesys.c
字号:
/* Copyright 1997, ESS Technology, Inc. *//* SCCSID @(#)filesys.c 4.36 03/16/05 *//* Based on iso9660.c 3.4 09/12/01 * * - Moved all menu related code to nav_menu.c/lc_menu.c. (PVu - 5/20/03) */#include <stdio.h>#include "vcxi.h"#include "const.h"#include "memmap.h"#include "buffer.h"#include "util.h"#include "dsa.h"#include "cd.h"#include "filesys.h"#include "flash.h"#include "nav_menu.h"#ifdef TWO_FIELDS_OSD#include "cg.h"#else#include "fsosd.h"#endif#ifdef MP3#include "mp3.h"#endif#ifdef MP3CDGint mp3cdg_file_cnt = 0;#endif/*------------------------------------------------------------------------ * Debugging macros *------------------------------------------------------------------------*/#ifdef DEBUG_OSDextern int osdreg;#define CPRINTF(a,b) {osdreg+=3;if(osdreg>13)osdreg=1;debug_osd(a,b,osdreg);}#else#define CPRINTF(a,b)#endif#if 0int bpt;#define BREAKPOINT(x) {bpt=x;while(bpt) VCX_service();}#else#define BREAKPOINT(x) #endif/*------------------------------------------------------------------------ * Private defines *------------------------------------------------------------------------*/#ifdef LONG_FILENAME_SUPP /* enable in filesys.h for Joliet support */ #define ItemNum 6#else#define ItemNum 12#endif LONG_FILENAME_SUPP #ifdef VCDLC#define MAX_SECTORS 4 /* max getSectors() size */#else#define MAX_SECTORS (VBV_size>>9) /* max getSectors() size */#endif/*------------------------------------------------------------------------ * Global or external variables *------------------------------------------------------------------------*/unsigned char real_track[MAX_DIR_CNT]; /* map to real track number */int real_track_cnt = 0; /* how many MP3 track we find *//*------------------------------------------------------------------------ * Private variables *------------------------------------------------------------------------*/static ushort dir_file_cnt;#ifdef UDFstatic int partition_start;static int main_start;#endif UDF#define ISO9660_FS 0#define UDF_FS 1#define UNKNOWN_FS (-1)static int fs_type; /* 0: ISO9660_FS, 1: UDF_FS */#ifdef ABNORMAL_VCDstatic int fs_scan_mode; /* 0: default, 1: file search mode */#endifSUF_ID suffix_filter[] = {#ifdef AVI_DEC {AVI_ID, ".AVI"},#endif#ifdef JPEG_DEC {JPEG_ID, ".JPG"}, {JPEG_ID, ".JPE"},#endif#ifdef WMA_DEC {WMA_ID, ".WMA"}, {WMA_ID, ".ASF"},#endif#ifdef MP3 {MP3_ID, ".MP3"}, {MP3_ID, ".MMP"},#endif#ifdef MP3CDG {MP3CDG_ID, ".CDG"},#endif#ifdef VGB {GAME_GB_ID, ".GB"}, {GAME_GB_ID, ".GBC"},#endif#ifdef INES {GAME_NES_ID, ".NES"}, {GAME_NES_ID, ".GUN"},#endif};/*------------------------------------------------------------------------ * Private functions *------------------------------------------------------------------------*/static int read_iso9660_dir(void);static int read_iso9660_files(void);static int rec_dir_file(int,int);static int search_dir_file(uchar *, uchar *, int, int);static void iso9660_assign_name(char *, char *, int, int);#ifdef RE_SORTstatic void iso9660_insort(int,int);#endif#if NOT_USEDint strncmp(char *s1, char *s2, int n);static int FS_find_file_loc(int, uchar *, int *);#endifstatic int bad_iso_directory_record(char *);static int iso9660_filename(char *, int);static int read_vol_table(void);#ifdef JPEG_DECstatic int is_FUJI_cd(int size);#endifstatic int iso9660_scan(int, int, int);static void FS_process_name(char *, char *, int, int);static int scan_getnsector(int, int, uchar *, PFI);#ifdef UDFstatic int UDF_read_ICB(int, int *, int *);static int UDF_find_partition(int, uchar *, int *);static int UDF_validate(int, uchar *, int *);static int UDF_find_root(void);static int UDF_read(void);#endif UDF#ifdef JPEG_DECstatic int FS_check_infocd(unsigned int);#endif JPEG_DECstatic uchar FS_filter_filename(unsigned char *, int);/* * mode==0 --- just search the string o */int iso_search_str(char *s, char *o, int buflen, char *target) { int i, len=0; char *x, *y, *z, *p; for(x=s,i=0;i<buflen;i++,x++) {#if 0 if (*x!=*o) continue;#endif for (y=x,z=o;*z&&*y==*z;y++) z++; if(z>o&&!*z) { return 1; } } return 0;}/* input: loc - in mm:ss:ff size - total scan size scan_task - scan function output: -2: no valid scan function -1: getSectors() failed 0: scan info not found status: status > 0, if successful*/static int scan_getnsector(int loc, int size, uchar *cptr, PFI scan_task){ static int scan_data; int get_size, status; if (!scan_task) return (-2); scan_data = 0; do { /* getSectors() limited by VBV size */ get_size = (size > MAX_SECTORS) ? MAX_SECTORS : size; if (getSectors(loc, get_size, 2048) < 1) { CPRINTF("FAILED GETNSECTOR",0); return (-1); } status = scan_task(get_size, cptr, &scan_data); if (status > 0) return (status); if (status < 0) break; size -= MAX_SECTORS; loc = adjCDtime(loc, logical2physical(get_size), 1); } while (size > 0); /* scan info not found */ return 0; }/* Function: processes file/directory names. Stores double-byte string as standard single-byte string. Also converts chars. to upper-case to simplify ensuing suffix pattern searches. input: psrc - pointer to unicode source string. pdst - pointer to resulting ascii string. len - length of string to be converted. dbyte - indicates double-byte chars. when non-zero. output: pdst - resulting single-byte ascii string.*/static void FS_process_name(char *psrc, char *pdst, int len, int dbyte){ int i, tmp, factor; uchar *psave; psave = pdst; factor = (dbyte) ? 2 : 1; /* Double-Byte chars ? */ for (i = (factor-1); i < len; i+=factor) { tmp = psrc[i]; if (tmp <= 'z' && tmp >= 'a') tmp = tmp - 0x20; /* ascii "toupper" */ *pdst++ = tmp; /* NOTE: only LSB byte is saved if unicode */ } }/* Function: Reads ISO9660 or UDF file systems. input: output: 0: failed 1: if success.*/int read_filesys(void) { int status; /* initialize */ dram_clear(ISO_start, ISO_size); iso9660_dir_cnt = iso9660_file_cnt = real_track_cnt = 0;#ifdef MP3CDG mp3cdg_file_cnt = 0;#endif#ifdef MULTI_EXT_FILE num_of_track = 0;#endif fs_type = UNKNOWN_FS; #ifdef JPEG_DEC is_fuji_cd = 0; is_Kodak_pictureCD = 0;#endif#ifdef UDF if (status = UDF_read()) { return (status>0); } else #endif if (status = read_iso9660(0)) { return (status>0); } else { /* unknown file system */ return 0; }}#ifdef SECONDARY_VOL_TABLE#define MAX_VOLUME_TABLES 5#else#define MAX_VOLUME_TABLES 1#endifint read_vol_table(void){ int i, table, vd_msf; struct iso_primary_descriptor *pvd, *svd; struct iso_directory_record *pdir; /* initialize..primary volume descriptor */ sec_vol_table = 0; table = 1; vd_msf = adjCDtime(last_session_msf, 0x216, 1); /* getSectors return values... * -2: force abort * -1: failed dsa_go() or servo problem * 0: no sync pattern * 1: if successful */ if (getSectors(vd_msf, MAX_VOLUME_TABLES, 2048) < 1) return -3; pvd = (struct iso_primary_descriptor *)dram(VBV_rdptr);#ifdef SECONDARY_VOL_TABLE for (i=1; i<MAX_VOLUME_TABLES; i++) { VBV_rdptr_advance(512); /* next vol descriptor location */ svd = (struct iso_primary_descriptor *)dram(VBV_rdptr); if ( (!strncmp(svd->id, "CD001", 5))&&((char)svd->type[0] == 2)) { sec_vol_table = 1; break; /* valid secondary volume descriptor found */ } } if (sec_vol_table) { table = 2; pvd = svd; }#endif pdir = (struct iso_directory_record *) pvd->root_directory_record; if ( (!strncmp(pvd->id, "CD001", 5))&&((char)pvd->type[0] == table)){ ROOT_loc = get_litend32(pdir->extent, 4); /* add 2047 to avoid truncation from bytes to sectors conversion */ ROOT_size = (get_litend32(pdir->size, 4) + 2047)>>11; /* sectors */ return 1; } else return 0; }/* input: mode - FS scan mode. 0: default data file scan mode 1: file search mode output: -3: getSectors() failed -2: no "valid" files found -1: error/abort during directory/file scan 0: not ISO9660 FS 1: if successful*/int read_iso9660(int mode){ int i;#ifdef ABNORMAL_VCD fs_scan_mode = mode;#endif for (i=0; i<MAX_DIR_CNT; i++) real_track[i] = 0; real_track_cnt = 0; i = read_vol_table(); if ( i <= 0 ) return (i); fs_type = ISO9660_FS; ROOT_loc = logical2physical(ROOT_loc+150); if (read_iso9660_dir()) return (-1); read_iso9660_files(); #ifdef DATA_CD if (iso9660_file_cnt){#ifdef ABNORMAL_VCD if (mode) return (1);#endif CDinfo.lasttrack = iso9660_file_cnt; CDinfo.firsttrack = 1; mp3_total_page = (real_track_cnt-1)/ItemNum;#ifndef MULTI_EXT_FILE num_of_track = iso9660_file_cnt;#endif mp3_menu_changed = 1; return 1; } else #endif { /* no target files found */ #ifdef JPEG_DEC is_Kodak_pictureCD = 0;#endif JPEG_DEC return (-2); }}static int read_iso9660_dir(void){ iso9660_dir[0].loc = ROOT_loc; iso9660_dir[0].size = ROOT_size; iso9660_dir[0].dir = -1; memcpy(iso9660_dir[0].name, MSG_root, 5); iso9660_dir_cnt++; if (iso9660_scan(ROOT_loc, ROOT_size, 0)) { return(-1); } return(0);}static int read_iso9660_files(void){ int i,j;#ifdef DATA_CD for (i=1; i<iso9660_dir_cnt; i++) { /* do not search ROOT */ CPRINTF(iso9660_dir[i].name, 0); if (iso9660_scan(iso9660_dir[i].loc, iso9660_dir[i].size, i)) { CPRINTF("DIR SCAN FAIL", iso9660_dir[i].loc); if (forceDSAabort) return (-1); continue; } }#endif return(0);}static int iso9660_scan(int loc, int size, int dir){ int get_size, mp3=0, status;#ifdef RE_SORT /* sort files within current directory */ iso9660_insort(1,iso9660_file_cnt); /* initialize for dir */#endif#ifdef MULTI_EXT_FILE dir_file_cnt = 0;#else dir_file_cnt = iso9660_file_cnt;#endif do { /* getSectors() limited by VBV size */ get_size = (size > MAX_SECTORS) ? MAX_SECTORS : size; status = getSectors(loc, get_size, 2048); /* -2: force abort
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -