static void init_sb(struct exfat_super_block* sb) { uint32_t clusters_max; uint32_t fat_sectors; clusters_max = get_volume_size() / get_cluster_size(); fat_sectors = DIV_ROUND_UP((loff_t) clusters_max * sizeof(cluster_t), get_sector_size()); memset(sb, 0, sizeof(struct exfat_super_block)); sb->jump[0] = 0xeb; sb->jump[1] = 0x76; sb->jump[2] = 0x90; memcpy(sb->oem_name, "EXFAT ", sizeof(sb->oem_name)); sb->sector_start = cpu_to_le64(get_first_sector()); sb->sector_count = cpu_to_le64(get_volume_size() / get_sector_size()); sb->fat_sector_start = cpu_to_le32( fat.get_alignment() / get_sector_size()); sb->fat_sector_count = cpu_to_le32(ROUND_UP( le32_to_cpu(sb->fat_sector_start) + fat_sectors, 1 << get_spc_bits()) - le32_to_cpu(sb->fat_sector_start)); sb->cluster_sector_start = cpu_to_le32( get_position(&cbm) / get_sector_size()); sb->cluster_count = cpu_to_le32(clusters_max - ((le32_to_cpu(sb->fat_sector_start) + le32_to_cpu(sb->fat_sector_count)) >> get_spc_bits())); sb->rootdir_cluster = cpu_to_le32( (get_position(&rootdir) - get_position(&cbm)) / get_cluster_size() + EXFAT_FIRST_DATA_CLUSTER); sb->volume_serial = cpu_to_le32(get_volume_serial()); sb->version.major = 1; sb->version.minor = 0; sb->volume_state = cpu_to_le16(0); sb->sector_bits = get_sector_bits(); sb->spc_bits = get_spc_bits(); sb->fat_count = 1; sb->drive_no = 0x80; sb->allocated_percent = 0; sb->boot_signature = cpu_to_le16(0xaa55); }
/* Check if we have any free file handles, and if we do, try to open the file specified. Supports absolute and relative paths */ int dfs_open(const char * const path) { /* Ensure we always open with a unique handle */ static uint32_t next_handle = 1; /* Try to find a free slot */ open_file_t *file = find_free_file(); if(!file) { return DFS_ENOMEM; } /* Try to find file */ directory_entry_t *dirent; int ret = recurse_path(path, WALK_OPEN, &dirent, TYPE_FILE); if(ret != DFS_ESUCCESS) { /* File not found, or other error */ return ret; } /* We now have the pointer to the file entry */ directory_entry_t t_node; grab_sector(dirent, &t_node); /* Set up file handle */ file->handle = next_handle++; file->size = get_size(&t_node); file->loc = 0; file->sector_number = 0; file->start_sector = get_first_sector(&t_node); grab_sector(file->start_sector, &file->cur_sector); return file->handle; }
/** Get all the entries in the directory @param fs FS_Instance to find all the information from @param directory To find all the entries for @return List of entries in the directory **/ FS_EntryList* get_entries(FS_Instance *fs, uint32_t directory) { uint8_t root_directory = find_root_of_directory(fs, directory); uint32_t bytes_per_cluster = ((!root_directory) ? fs->BPB_SecPerClus : 1) * fs->BPB_BytsPerSec; uint32_t entries_per_cluster = bytes_per_cluster / sizeof(FatEntry); FatEntry *entries = malloc(entries_per_cluster * sizeof(FatEntry)); if(NULL == entries) { return NULL; } uint16_t *long_name = NULL; FS_EntryList *list_head = NULL; FS_EntryList *list_tail = NULL; if(root_directory) { directory = fs->current_directory_position; } do { uint64_t seek = directory; if(!root_directory) { seek = get_first_sector(fs, directory); } fseek(fs->image, (seek * fs->BPB_BytsPerSec), SEEK_SET); fread(entries, sizeof(FatEntry), entries_per_cluster, fs->image); for(int i = 0; i < entries_per_cluster; i++) { FatEntry *entry = &(entries[i]); if(0x00 == entry->DIR_Name[0]) { break; } if(0xE5 == entry->DIR_Name[0]) { continue; } if(0x05 == entry->DIR_Name[0]) { entry->DIR_Name[0] = 0xE5; } if(!check_mask(entry->DIR_Attr, ATTR_LONG_NAME)) { uint8_t valid = 1; for (int j = 0; j < DIR_Name_LENGTH; j++) { if (0x20 > entry->DIR_Name[j]) { valid = 0; } } if(!valid) { continue; } FS_EntryList *listEntry = malloc(sizeof(FS_EntryList)); listEntry->node = malloc(sizeof(FS_Entry)); listEntry->node->entry = malloc(sizeof(FatEntry)); memcpy(listEntry->node->entry, entry, sizeof(FatEntry)); listEntry->node->file_name = long_name; long_name = NULL; listEntry->next = NULL; if(NULL != list_tail) { list_tail->next = listEntry; } list_tail = listEntry; if(NULL == list_head) { list_head = listEntry; } } } if(!root_directory) { directory = find_first_entry(fs, directory); } else { directory++; } } while(root_directory ? (directory < (fs->current_directory_position + fs->root_sectors)) : !is_eof(fs, directory)); free(entries); return list_head; }