Example #1
0
int get_entry(int count, FILE *infile, struct program_block *program) {
    switch (detect_type(infile)) {
    case t64:
    {
        unsigned int offset;

        if (!get_entry_info(count, infile, &program->info, &offset))
            return 0;
        if (fseek(infile, offset, SEEK_SET) != 0)
            return 0;
    }
    if (fread(&program->data, 1, program->info.end - program->info.start, infile) < 1)
        return 0;
    return 1;
    case p00:
    case prg:
        return get_first_entry(infile, program);
    default:
        return 0;
    }
}
Example #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 ;
}
Example #3
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 ;
}
Example #4
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;
}
Example #5
0
static UINT_PTR APIENTRY frompc_hook_proc(HWND hwnd, UINT uimsg, WPARAM wparam, LPARAM lparam){
  HWND preview;
  char filename[256];
  LVCOLUMNA column;

  preview = GetDlgItem(hwnd, IDC_PREVIEW);
  switch (uimsg) {
  case WM_INITDIALOG:
    column.mask = LVCF_TEXT | LVCF_WIDTH;
    column.pszText = "No.";
    column.cx = 40;
    ListView_InsertColumn(preview, 0, &column);
    column.pszText = "Name";
    column.cx = 160;
    ListView_InsertColumn(preview, 1, &column);
    column.pszText = "Start address";
    column.cx = 80;
    ListView_InsertColumn(preview, 2, &column);
    column.pszText = "End address";
    ListView_InsertColumn(preview, 3, &column);

    SendMessage(GetDlgItem(hwnd, IDC_C64_NAME), EM_LIMITTEXT, 16, 0);

    break;
  case WM_NOTIFY:
    {
      LPOFNOTIFY notify = (LPOFNOTIFY) lparam;
      if (notify->hdr.code == CDN_SELCHANGE) {
        ListView_DeleteAllItems(preview);
        SetDlgItemTextA(hwnd, IDC_C64_NAME, "");
        EnableWindow(GetDlgItem(hwnd, IDC_C64_NAME), FALSE);
        if (CommDlg_OpenSave_GetFilePath
            (notify->hdr.hwndFrom, filename, 256) >= 0)
          write_entries_to_window(hwnd, filename);
      }
      else if (notify->hdr.code == CDN_FILEOK) {
        int entry_num;
        struct simple_block_list_element **block = (struct simple_block_list_element **)notify->lpOFN->lCustData;
        FILE *fd = NULL;

        if (CommDlg_OpenSave_GetFilePath(notify->hdr.hwndFrom, filename, 256)
            < 0) {
          MessageBoxA(hwnd, "Cannot get selected file name", "WAV-PRG error",
                     MB_ICONERROR);
        }
        else
          fd = fopen(filename, "rb");
        if (fd == NULL) {
          MessageBoxA(hwnd, "Cannot open selected file", "WAV-PRG error",
                     MB_ICONERROR);
          SetWindowLong(hwnd, DWL_MSGRESULT, -1);
        }
        else
        {
          switch (detect_type(fd)) {
          case not_a_valid_file:
            MessageBoxA(hwnd, "Selected file is not a supported file",
                       "WAV-PRG error", MB_ICONERROR);
            break;
          case t64:
            {
              int index;
              struct simple_block_list_element **current_block = block;

              for (index = ListView_GetNextItem(preview, -1, LVNI_SELECTED); index != -1; index = ListView_GetNextItem(preview, index, LVNI_SELECTED)) {
                LVITEMA sel_item;
                char sel_num[6];

                sel_item.mask = LVIF_TEXT;
                sel_item.iItem = index;
                sel_item.iSubItem = 0;
                sel_item.pszText = sel_num;
                sel_item.cchTextMax = sizeof(sel_num);
                if (!ListView_GetItem(preview, &sel_item))
                  continue;
                entry_num = atoi(sel_num);
                add_simple_block_list_element(current_block);
                if (!get_entry(entry_num, fd, &(*current_block)->block)){
                  remove_simple_block_list_element(current_block);
                  continue;
                }
                current_block = &(*current_block)->next;
              }
            }
            if (*block == NULL)
              add_all_entries_from_file(block, fd);

            if (*block == NULL)
              MessageBoxA(hwnd, "You chose a T64 file with no entries",
                          "WAV-PRG error", MB_ICONERROR);
            break;
          case p00:
          case prg:
            add_simple_block_list_element(block);
            if (!get_first_entry(fd, &(*block)->block)) {
              MessageBoxA(hwnd, "Error in reading file", "WAV-PRG error",
                         MB_ICONERROR);
              remove_simple_block_list_element(block);;
            }
            else
            {
              int i;
              char pad_with_spaces = 0;

              GetDlgItemTextA(hwnd, IDC_C64_NAME, (*block)->block.info.name, 17);
              for (i = 0; i < 16; i++) {
                if ((*block)->block.info.name[i] == 0)
                  pad_with_spaces = 1;
                if (pad_with_spaces)
                  (*block)->block.info.name[i] = 32;
              }
            }
            break;
          default:
            break;
          }
        }
        if (fd != NULL)
          fclose(fd);
        if (*block == NULL){
          SetWindowLong(hwnd, DWL_MSGRESULT, -1);
          return 1;
        }
      }
      break;
    }
  default:
    break;
  }
  return 0;
}
Example #6
0
/* Walk a path string, either changing directories or finding the right path

   If mode is WALK_CHDIR, the result of this function is entering into the new
   directory on success, or the old directory being returned on failure.

   If mode is WALK_OPEN, the result of this function is the directory remains
   unchanged and a pointer to the directory entry for the requested file or
   directory is returned.  If it is a file, the directory entry for the file
   itself is returned.  If it is a directory, the directory entry of the first
   file or directory inside that directory is returned. 
 
   The type specifier allows a person to specify that only a directory or file
   should be returned.  This works for WALK_OPEN only. */
static int recurse_path(const char * const path, int mode, directory_entry_t **dirent, int type)
{
    int ret = DFS_ESUCCESS;
    char token[MAX_FILENAME_LEN+1];
    char *cur_path = (char *)path;
    uint32_t dir_stack[MAX_DIRECTORY_DEPTH];
    uint32_t dir_loc = directory_top;
    int last_type = TYPE_ANY;
    int ignore = 1; // Do not, by default, read again during the first while

    /* Save directory stack */
    memcpy(dir_stack, directories, sizeof(uint32_t) * MAX_DIRECTORY_DEPTH);

    /* Grab first token, make sure it isn't root */
    cur_path = get_next_token(cur_path, token);

    if(strcmp(token, "/") == 0)
    {
        /* It is an absolute path */
        clear_directory();

        /* Ensure that we remember this as a directory */
        last_type = TYPE_DIR;

        /* We need to read through the first while loop */
        ignore = 0;
    }

    /* Loop through the rest */
    while(cur_path || ignore)
    {
        /* Grab out the next token */
        if(!ignore) { cur_path = get_next_token(cur_path, token); }
        ignore = 0;

        if( (token[0] == '/' || token[0] == '.') )
        {
	    if(token[1] == '.')
		pop_directory();/* Up one directory */

            last_type = TYPE_DIR;
        }
        else
        {
            /* Find directory entry, push */
            directory_entry_t *tmp_node = find_dirent(token, peek_directory());

            if(tmp_node)
            {
                /* Grab node, make sure it is a directory, push subdirectory, try again! */
                directory_entry_t node;
                grab_sector(tmp_node, &node);

                uint32_t flags = get_flags(&node);

                if(FILETYPE(flags) == FLAGS_DIR)
                {
                    /* Push subdirectory onto stack and loop */
                    push_directory(get_first_entry(&node));
                    last_type = TYPE_DIR;
                }
                else
                {
                    if(mode == WALK_CHDIR)
                    {
                        /* Not found, this is a file */
                        ret = DFS_ENOFILE;
                        break;
                    }
                    else
                    {
                        last_type = TYPE_FILE;

                        /* Only count if this is the last thing we are doing */
                        if(!cur_path)
                        {
                            /* Push file entry onto stack in preparation of a return */
                            push_directory(tmp_node);
                        }
                        else
                        {
                            /* Not found, this is a file */
                            ret = DFS_ENOFILE;
                            break;
                        }
                    }
                }
            }
            else
            {
                /* Not found! */
                ret = DFS_ENOFILE;
                break;
            }
        }
    }

    if(type != TYPE_ANY && type != last_type)
    {
        /* Found an entry, but it was the wrong type! */
        ret = DFS_ENOFILE;
    }

    if(mode == WALK_OPEN)
    {
        /* Must return the node found if we found one */
        if(ret == DFS_ESUCCESS && dirent)
        {
            *dirent = peek_directory();
        }
    }

    if(mode == WALK_OPEN || ret != DFS_ESUCCESS)
    {
        /* Restore stack */
        directory_top = dir_loc;
        memcpy(directories, dir_stack, sizeof(uint32_t) * MAX_DIRECTORY_DEPTH);
    }

    return ret;
}
Example #7
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;
}
Example #8
0
/*
   함수명  : writeDirEntryInDirCluster
   하는일  : 디렉토리 클러스터안에 디렉토리 엔트리를 추가한다.
   디렉토리의 모든 클러스터를 검사하여, 빈 엔트리를 찾고 그 위치에 디렉토리 엔트리를 추가한다.
   인자    : fVolume :  루프백이미지/파일 볼륨의 포인터
nDirClusterNumber : 디렉토리 클러스터 번호
pDirectoryEntry : 디렉토리 엔트리의 포인터
pFileName : 파일 이름의 문자열 포인터
리턴 값 : BOOL
 */
BOOL alloc_new_dirent(struct mfs_volume* volume, u128 dir_cluster_number, struct mfs_dirent* dirent, ps16_t file_name)
{

	u8_t cluster[CLUSTER_SIZE] = {0, };
	const u32_t entry_per_data_cluster = CLUSTER_SIZE / sizeof(struct mfs_dirent);
	BOOL has_long_file_name_next_entry = FALSE;
	u128 read_position = 0;
	u128 wirte_position = 0;
	u128 current_cluster_number = dir_cluster_number;
	u128 before_cluster_number = 0;
	u32_t current_entry_number = 0;
	struct mfs_dirent* current_dirent = NULL;
	u128 end_cluster = get_end_cluster(volume);

	// 디렉토리의 모든 클러스터를 검사한다. 
	while(current_cluster_number != end_cluster)
	{
		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_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)
			if( is_deleted_file(current_dirent->attribute) || is_deleted_dir(current_dirent->attribute) )
			{
				wirte_position = read_position + (current_entry_number * sizeof(struct mfs_dirent));

#ifdef __KERNEL__
				seek_volume(volume, wirte_position);
#else
				seek_volume(volume, wirte_position, SEEK_SET);
#endif

				write_volume(volume, dirent, sizeof(struct mfs_dirent), 1);

				printf("alloc_new_dirent %d %d\n", current_cluster_number, wirte_position);

				return TRUE;
			}

			// 다음 엔트리를 얻는다.
			current_dirent = get_next_entry(cluster, &current_entry_number, &has_long_file_name_next_entry);
		}

		before_cluster_number = current_cluster_number;
		current_cluster_number = read_fat_index(volume, current_cluster_number);
	}

	// 디렉토리 클러스터에 빈 공간이 없다, 클러스터 추가
	current_cluster_number = find_empty_fat_index(volume);

	write_in_fat_index(volume, before_cluster_number, current_cluster_number);
	write_in_fat_index(volume, current_cluster_number, end_cluster);

	wirte_position = read_cluster(volume, current_cluster_number);

#ifdef __KERNEL__
	seek_volume(volume, wirte_position);
#else
	seek_volume(volume, wirte_position, SEEK_SET);
#endif
	write_volume(volume, dirent, sizeof(struct mfs_dirent), 1);

	printf("alloc_new_dirent %d %d\n", current_cluster_number, wirte_position);

	return TRUE;
}
Example #9
0
u32_t get_cluster_number(struct mfs_volume* volume, ps16_t path)
{
	u8_t current_cluster[CLUSTER_SIZE] = {0, };
	ps16_t seperated_path = strtok(path, "/");
	const u32_t entry_per_data_cluster = CLUSTER_SIZE / sizeof(struct mfs_dirent);
	struct mfs_dirent* current_dir_entry = NULL;
	s16_t composited_file_name[128] = {0, };
	u128 current_cluster_number = 2;	// Root Directory의 클러스터 값
	u32_t current_entry_number = 0;
	BOOL is_dir_changed = FALSE;
	BOOL has_long_file_name_next_entry = FALSE;
	u128 end_cluster = get_end_cluster(volume);
	u128 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, current_cluster, sizeof(u8_t), CLUSTER_SIZE);

	while(seperated_path != NULL)
	{
		is_dir_changed = FALSE;

		// 클러스터의 첫 엔트리를 얻는다.
		current_dir_entry = get_first_entry(current_cluster, &current_entry_number, has_long_file_name_next_entry);

		// 클러스터의 모든 엔트리를 검사한다.
		while(current_entry_number != entry_per_data_cluster)
		{

			// 얻은 엔트리가 폴더일 경우
			if(is_normal_dir(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(seperated_path, composited_file_name))
				{
					// 일치한다면 다음 route 경로 명을 얻는다.
					seperated_path = strtok(NULL, "/");

					current_cluster_number = current_dir_entry->head_cluster_number;
					is_dir_changed = TRUE;
					break;
				}
			}

			// 다음 엔트리를 얻는다.
			current_dir_entry = get_next_entry(current_cluster, &current_entry_number, &has_long_file_name_next_entry);
		}

		// 현재 탐색 디렉토리가 변경되지 않았다면 현재 디렉토리의 다음 클러스터를 얻는다.
		if (is_dir_changed == FALSE)
		{
			current_cluster_number = read_fat_index(volume, current_cluster_number);

			// route 경로가 잘못되었다.
			if(current_cluster_number == end_cluster)
			{
				printf("wrong route\n");
				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, current_cluster, sizeof(u8_t), CLUSTER_SIZE);
	}

	return current_cluster_number;
}