blargg_err_t Zip_Extractor::update_info( bool advance_first ) { while ( 1 ) { entry_t& e = (entry_t&) catalog [(size_t)catalog_pos]; if ( memcmp( e.type, "\0K\1\2P", 5 ) && memcmp( e.type, "PK\1\2", 4 ) ) { check( !memcmp( e.type, "\0K\5\6P", 5 ) ); break; } unsigned len = get_le16( e.filename_len ); BOOST::int64_t next_offset = catalog_pos + entry_size + len + get_le16( e.extra_len ) + get_le16( e.comment_len ); if (isZIP64) { if ((unsigned)next_offset > catalog.size() - end64_entry_size) return blargg_err_file_corrupt; } else { if ((unsigned)next_offset > catalog.size() - end_entry_size) return blargg_err_file_corrupt; } if ( catalog [(size_t)next_offset] == 'P' ) reorder_entry_header( (long)next_offset ); if ( !advance_first ) { e.filename [len] = 0; // terminate name if ( is_normal_file( e, len ) ) { set_name( e.filename ); set_info( get_le32( e.size ), get_le32( e.date ), get_le32( e.crc ) ); break; } } catalog_pos = next_offset; advance_first = false; } return blargg_ok; }
void __mfs_readdir(const ps16_t route, struct file *file, struct dir_context *ctx) { u8_t cluster[CLUSTER_SIZE] = {0, }; const u32_t entry_per_data_cluster = CLUSTER_SIZE / sizeof(struct mfs_dirent); s16_t composited_file_name[128] = {0, }; BOOL has_long_file_name_entry = FALSE; u128 current_cluster_number = 0; u32_t current_entry_number = 0; u128 read_position = 0; struct mfs_dirent* current_dirent = NULL; static s16_t path[1024]={0}; struct dentry *de = file->f_dentry; struct mfs_volume* volume = de->d_sb->s_fs_info; u128 end_cluster = get_end_cluster(volume); strncpy(path, route, 1024); current_cluster_number = get_cluster_number(volume, path); if(current_cluster_number == 0) { return ; } printk("__mfs_readdir\n"); // 볼륨이 무효하다. if(volume == NULL) return ; read_position = read_cluster(volume, current_cluster_number); #ifdef __KERNEL__ seek_volume(volume, read_position); #else seek_volume(volume, read_position, SEEK_SET); #endif read_volume(volume, cluster, sizeof(u8_t), CLUSTER_SIZE); printk("current cluster number before : %d\n", current_cluster_number); while(current_cluster_number != end_cluster) { // 클러스터의 첫 엔트리를 얻는다. current_dirent = get_first_entry(cluster, ¤t_entry_number, has_long_file_name_entry); printk("current dentry : %x\n", current_dirent); // 클러스터의 모든 엔트리를 검사한다. while(current_entry_number != entry_per_data_cluster) { printk("current cluster number after : %d\n", current_cluster_number); // if(current_dirent->size != 0) { // printk("current_dentry size is NOT 0\n"); // 얻은 엔트리가 LongFileName인지 여부 검사 if(is_long_file_name(current_dirent->attribute) == TRUE) { // LongFileName일 경우 LongFileName을 조합한다. composite_long_file_name(volume, current_cluster_number, current_entry_number, composited_file_name); } else { // 일반 FileName일 경우 복사 strcpy(composited_file_name, current_dirent->name); } if(is_normal_dir(current_dirent->attribute) == TRUE) { static char buf[1024]=""; int len; buf[0]='\0'; strcat(buf,path); len=strlen(path); if(len > 0){ if(path[len-1] != '/') strcat(buf,"/"); } strcat(buf, composited_file_name); if(!dir_emit(ctx, composited_file_name, strlen(composited_file_name), 2, DT_DIR)) { printk("WARNING %s %d", __FILE__, __LINE__); return ; } ctx->pos++; strcat(buf, "*<DIR>\n"); printk(buf); } else if(is_normal_file(current_dirent->attribute) == TRUE) { static char buf[1024]=""; buf[0]='\0'; if(!dir_emit(ctx, composited_file_name, strlen(composited_file_name), 2, DT_REG)) { printk("WARNING %s %d", __FILE__, __LINE__); return ; } ctx->pos++; strcat(buf, composited_file_name); strcat(buf, "*<FILE>\n"); printk(buf); } // } // 다음 엔트리를 얻는다. current_dirent = get_next_entry(cluster, ¤t_entry_number, &has_long_file_name_entry); } current_cluster_number = read_fat_index(volume, current_cluster_number); // 지정된 번호의 클러스터를 읽는다. read_position = read_cluster(volume, current_cluster_number); #ifdef __KERNEL__ seek_volume(volume, read_position); #else seek_volume(volume, read_position, SEEK_SET); #endif read_volume(volume, cluster, sizeof(u8_t), CLUSTER_SIZE); } return ; }
int __mfs_lookup(struct mfs_volume* volume, const ps16_t route, const ps16_t file_name) { u8_t cluster[CLUSTER_SIZE] = {0, }; const u32_t entry_per_data_cluster = CLUSTER_SIZE / sizeof(struct mfs_dirent); s16_t composited_file_name[128] = {0, }; BOOL has_long_file_name_next_entry = FALSE; u128 current_cluster_number = 0; u32_t current_entry_number = 0; u128 read_position = 0; struct mfs_dirent* current_dentry = NULL; static s16_t path[1024]={0}; u128 end_cluster = get_end_cluster(volume); strncpy(path, route, 1024); current_cluster_number = get_cluster_number(volume, route); // if(current_cluster_number == 0) // { // return 0; // } // 볼륨이 무효하다. if(volume == NULL) return 0; read_position = read_cluster(volume, current_cluster_number); #ifdef __KERNEL__ seek_volume(volume, read_position); #else seek_volume(volume, read_position, SEEK_SET); #endif read_volume(volume, cluster, sizeof(u8_t), CLUSTER_SIZE); while(current_cluster_number != end_cluster) { // 클러스터의 첫 엔트리를 얻는다. current_dentry = get_first_entry(cluster, ¤t_entry_number, has_long_file_name_next_entry); // 클러스터의 모든 엔트리를 검사한다. while(current_entry_number != entry_per_data_cluster) { // 얻은 엔트리가 LongFileName인지 여부 검사 if(is_long_file_name(current_dentry->attribute) == TRUE) { // LongFileName일 경우 LongFileName을 조합한다. composite_long_file_name(volume, current_cluster_number, current_entry_number, composited_file_name); } else { // 일반 FileName일 경우 복사 strcpy(composited_file_name, current_dentry->name); } if(strcmp(composited_file_name, file_name) == 0){ if(is_normal_dir(current_dentry->attribute) == TRUE){ return DIR_DENTRY; } else if(is_normal_file(current_dentry->attribute) == TRUE){ return FILE_DENTRY; } } // 다음 엔트리를 얻는다. current_dentry = get_next_entry(cluster, ¤t_entry_number, &has_long_file_name_next_entry); } current_cluster_number = read_fat_index(volume, current_cluster_number); // 지정된 번호의 클러스터를 읽는다. read_position = read_cluster(volume, current_cluster_number); #ifdef __KERNEL__ seek_volume(volume, read_position); #else seek_volume(volume, read_position, SEEK_SET); #endif read_volume(volume, cluster, sizeof(u8_t), CLUSTER_SIZE); } return 0; }
void __mfs_readdir(struct mfs_volume* volume, const ps16_t route, struct printdir *printdir) { u8_t cluster[CLUSTER_SIZE] = {0, }; const u32_t entry_per_data_cluster = CLUSTER_SIZE / sizeof(struct mfs_dirent); s16_t composited_file_name[128] = {0, }; BOOL has_long_file_name_next_entry = FALSE; u128 current_cluster_number = 0; u32_t current_entry_number = 0; u128 read_position = 0; struct mfs_dirent* current_dirent = NULL; static s16_t path[1024]={0}; struct file* filp = printdir->filp; void* dirent = printdir->dirent; filldir_t filldir = printdir->filldir; u128 end_cluster = get_end_cluster(volume); strncpy(path, route, 1024); current_cluster_number = get_cluster_number(volume, path); if(current_cluster_number == 0) { return ; } // 볼륨이 무효하다. if(volume == NULL) return ; read_position = read_cluster(volume, current_cluster_number); seek_volume(volume, read_position); read_volume(volume, cluster, sizeof(u8_t), CLUSTER_SIZE); while(current_cluster_number != end_cluster) { // 클러스터의 첫 엔트리를 얻는다. current_dirent = get_first_entry(cluster, ¤t_entry_number, has_long_file_name_next_entry); // 클러스터의 모든 엔트리를 검사한다. while(current_entry_number != entry_per_data_cluster) { // if(current_dirent->size != 0) // { // 얻은 엔트리가 LongFileName인지 여부 검사 if(is_long_file_name(current_dirent->attribute) == TRUE) { // LongFileName일 경우 LongFileName을 조합한다. composite_long_file_name(volume, current_cluster_number, current_entry_number, composited_file_name); } else { // 일반 FileName일 경우 복사 strcpy(composited_file_name, current_dirent->name); } if(is_normal_dir(current_dirent->attribute) == TRUE) { static char buf[1024] = ""; int len; buf[0] = '\0'; strcat(buf, path); len = strlen(path); if(len > 0){ if(path[len-1] != '/') strcat(buf, "/"); } strcat(buf, composited_file_name); if(filldir(dirent, composited_file_name, strlen(composited_file_name), filp->f_pos++, 2, DT_DIR)){ printk("WARNING %s %d", __FILE__,__LINE__); return ; } strcat(buf, "*<DIR>\n"); printk(buf); } else if(is_normal_file(current_dirent->attribute) == TRUE) { static char buf[1024]=""; buf[0]='\0'; printk("garig %p %p %p %s\n", filp, dirent, filldir, composited_file_name); if(filldir(dirent, composited_file_name, strlen(composited_file_name), filp->f_pos++, 2, DT_REG)){ printk("WARNING %s %d", __FILE__, __LINE__); return ; } strcat(buf, composited_file_name); strcat(buf, "*<FILE>\n"); printk(buf); } // } // 다음 엔트리를 얻는다. current_dirent = get_next_entry(cluster, ¤t_entry_number, &has_long_file_name_next_entry); } current_cluster_number = read_fat_index(volume, current_cluster_number); // 지정된 번호의 클러스터를 읽는다. read_position = read_cluster(volume, current_cluster_number); seek_volume(volume, read_position); read_volume(volume, cluster, sizeof(u8_t), CLUSTER_SIZE); } return ; }
blargg_err_t Zip_Extractor::update_info( bool advance_first ) { while ( 1 ) { entry_t& e = (entry_t&) catalog [catalog_pos]; if ( memcmp( e.type, "\0K\1\2P", 5 ) && memcmp( e.type, "PK\1\2", 4 ) ) { check( !memcmp( e.type, "\0K\5\6P", 5 ) ); break; } unsigned len = get_le16( e.filename_len ); int next_offset = catalog_pos + entry_size + len + get_le16( e.extra_len ) + get_le16( e.comment_len ); if ( (unsigned) next_offset > catalog.size() - end_entry_size ) return blargg_err_file_corrupt; if ( catalog [next_offset] == 'P' ) reorder_entry_header( next_offset ); if ( !advance_first ) { char unterminate = e.filename[len]; e.filename [len] = 0; // terminate name std::string fname = e.filename; if ( is_normal_file( e, len ) ) { e.filename[len] = unterminate; name.resize(fname.size()+1); if(len != 0) { memcpy(name.begin(),fname.c_str(),len); name[name.size()-1] = 0; } set_name( name.begin() ); set_info( get_le32( e.size ), get_le32( e.date ), get_le32( e.crc ) ); unsigned extra_len = get_le32(e.extra_len); //walk over extra fields unsigned i = len; while(i < extra_len + len) { unsigned id = get_le16(e.filename + i); i += 2; unsigned exlen = get_le16(e.filename + i); i += 2; int exfield = i; i += exlen; if(id == 0x7075) //INFO-ZIP unicode path extra field (contains version, checksum, and utf-8 filename) { unsigned version = (unsigned char)*(e.filename + exfield); if(version == 1) { exfield += 1; //skip version exfield += 4; //skip crc //the remainder is a utf-8 filename int fnamelen = exlen-5; char* tempbuf = (char*)malloc(fnamelen + 1); memcpy(tempbuf,e.filename + exfield, fnamelen); tempbuf[fnamelen] = 0; wchar_t* wfname_buf = blargg_to_wide(tempbuf); std::wstring wfname = wfname_buf; free(tempbuf); free(wfname_buf); size_t wfname_len = wfname.size(); this->wname.resize(wfname_len+1); if(wfname_len != 0) { memcpy(this->wname.begin(),wfname.c_str(),wfname_len*sizeof(wchar_t)); wname[wname.size()-1] = 0; } set_name( name.begin(), wname.begin() ); } } } break; } } catalog_pos = next_offset; advance_first = false; } return blargg_ok; }
/* 함수명 : search_fileDirectoryEntryInDirCluster 하는일 : 디렉토리 클러스터 안에 파일 디렉토리 엔트리를 찾는다. 디렉토리가 가지고 있는 모든 클러스터를 순환하여 파일 이름과 같은 엔트리를 찾는다. 인자 : fVolume : 루프백이미지/파일 볼륨의 포인터 nDirClusterNumber : 디렉토리 클러스터 번호 pFileName : 파일이름의 문자열 포인터 pSearchedDirEntry : 검색된 디렉토리 엔트리의 포인터 리턴 값 : BOOL */ BOOL get_dentry(struct mfs_volume* volume, u128 dir_cluster_number, ps16_t file_name, struct mfs_dirent* searched_dir_entry) { u8_t cluster[CLUSTER_SIZE] = {0, }; const u32_t entry_per_data_cluster = CLUSTER_SIZE / sizeof(struct mfs_dirent); s16_t composited_file_name[128] = {0, }; BOOL has_long_file_name_next_entry = FALSE; u128 read_position = 0; u128 current_cluster_number = dir_cluster_number; u32_t current_entry_number = 0; struct mfs_dirent* current_dir_entry = NULL; u128 end_cluster = get_end_cluster(volume); printf("get_dentry: %s\n", file_name); // 디렉토리의 모든 클러스터를 검사한다. while(current_cluster_number != end_cluster) { printf("current_cluster_number: %d\n", current_cluster_number); read_position = read_cluster(volume, current_cluster_number); #ifdef __KERNEL__ seek_volume(volume, read_position); #else seek_volume(volume, read_position, SEEK_SET); #endif read_volume(volume, cluster, sizeof(u8_t), CLUSTER_SIZE); current_dir_entry = get_first_entry(cluster, ¤t_entry_number, has_long_file_name_next_entry); while(current_entry_number != entry_per_data_cluster) { printf("current entry number after : %d\n", current_entry_number); if(is_normal_file(current_dir_entry->attribute) == TRUE) { // 얻은 엔트리가 LongFileName인지 여부 검사 if(is_long_file_name(current_dir_entry->attribute) == TRUE) { // LongFileName일 경우 LongFileName을 조합한다. composite_long_file_name(volume, current_cluster_number, current_entry_number, composited_file_name); } else { // 일반 FileName일 경우 복사 strcpy(composited_file_name, current_dir_entry->name); } // Name 비교 if(!strcmp(file_name, composited_file_name)) { memcpy(searched_dir_entry, current_dir_entry, sizeof(struct mfs_dirent)); return TRUE; } } // 다음 엔트리를 얻는다. current_dir_entry = get_next_entry(cluster, ¤t_entry_number, &has_long_file_name_next_entry); } current_cluster_number = read_fat_index(volume, current_cluster_number); printf("read fat index : %d\n", current_cluster_number); } printf("file not exist\n"); return FALSE; }