Пример #1
0
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;
}
Пример #2
0
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, &current_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, &current_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 ;
}
Пример #3
0
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, &current_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, &current_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;
}
Пример #4
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, &current_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, &current_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 ;
}
Пример #5
0
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;
}
Пример #6
0
/*
   함수명  : 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, &current_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, &current_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;
}