fat12: add ls_callback function

Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
Sean Cross 2019-06-10 22:29:21 +08:00
parent c4c5f706b0
commit 03e268f710
3 changed files with 90 additions and 5 deletions

View File

@ -4,16 +4,28 @@
#include <stdint.h> #include <stdint.h>
struct fat12_partition; struct fat12_partition;
struct fat12_dirent {
char filename[256];
uint32_t first_cluster;
uint32_t size;
uint32_t file_attributes;
uint32_t ctime;
uint32_t mtime;
};
struct fat12_partition * fat12_alloc(void); struct fat12_partition * fat12_alloc(void);
int fat12_open(struct fat12_partition *part, const char *filename); int fat12_open(struct fat12_partition *part, const char *filename);
int fat12_close(struct fat12_partition *part); int fat12_close(struct fat12_partition *part);
void fat12_free(struct fat12_partition **part); void fat12_free(struct fat12_partition **part);
int fat12_ls_foreach(struct fat12_partition *part, uint32_t dir_cluster, void *data, int (*callback)(void *data, const struct fat12_dirent *dirent));
void fat12_write_u8(void *ptr, uint8_t val); void fat12_write_u8(void *ptr, uint8_t val);
uint8_t fat12_read_u8(void *ptr); uint8_t fat12_read_u8(void *ptr);
void fat12_write_u16(void *ptr, uint16_t val); void fat12_write_u16(void *ptr, uint16_t val);
uint16_t fat12_read_u16(void *ptr); uint16_t fat12_read_u16(void *ptr);
void fat12_write_u32(void *ptr, uint32_t val);
uint32_t fat12_read_u32(void *ptr);
void fat12_set_cluster(void *fat, uint32_t cluster, uint32_t value); void fat12_set_cluster(void *fat, uint32_t cluster, uint32_t value);
uint32_t fat12_get_cluster(void *fat, uint32_t cluster); uint32_t fat12_get_cluster(void *fat, uint32_t cluster);

View File

@ -50,6 +50,22 @@ uint16_t fat12_read_u16(void *ptr) {
return val; return val;
} }
void fat12_write_u32(void *ptr, uint32_t val) {
((uint8_t *)ptr)[0] = (val >> 0) & 0xff;
((uint8_t *)ptr)[1] = (val >> 8) & 0xff;
((uint8_t *)ptr)[2] = (val >> 16) & 0xff;
((uint8_t *)ptr)[3] = (val >> 24) & 0xff;
}
uint32_t fat12_read_u32(void *ptr) {
uint16_t val = 0;
val |= (((uint8_t *)ptr)[0] << 0) & 0x000000ff;
val |= (((uint8_t *)ptr)[1] << 8) & 0x0000ff00;
val |= (((uint8_t *)ptr)[2] << 16) & 0x00ff0000;
val |= (((uint8_t *)ptr)[3] << 24) & 0xff000000;
return val;
}
void fat12_set_cluster(void *fat, uint32_t cluster, uint32_t value) { void fat12_set_cluster(void *fat, uint32_t cluster, uint32_t value) {
uint32_t offset = (cluster * 3) / 2; uint32_t offset = (cluster * 3) / 2;
if (cluster&1) { if (cluster&1) {
@ -119,6 +135,9 @@ int fat12_open(struct fat12_partition *part, const char *filename) {
part->cluster_count = bytes / part->sector_size / part->cluster_size; part->cluster_count = bytes / part->sector_size / part->cluster_size;
part->cluster_bytes = (part->cluster_count * 3) / 2; part->cluster_bytes = (part->cluster_count * 3) / 2;
// Move to the root directory
part->current_cluster = part->first_offset;
/// ///
fprintf(stderr, "part->sector_size: %d\n", part->sector_size); fprintf(stderr, "part->sector_size: %d\n", part->sector_size);
@ -141,6 +160,53 @@ int fat12_open(struct fat12_partition *part, const char *filename) {
return 0; return 0;
} }
static int fat12_ls_foreach_sector(struct fat12_partition *part, uint32_t sector, uint32_t count,
void *data, int (*callback)(void *data, const struct fat12_dirent *dirent)) {
struct fat12_dirent dirent;
uint8_t buf[part->sector_size];
uint32_t offset;
pang_seek(part->fd, sector * part->sector_size, SEEK_SET);
pang_read(part->fd, buf, sizeof(buf));
for (offset = 0; offset < count; offset++) {
struct fat_directory_entry *entry = &((struct fat_directory_entry *)buf)[offset];
memset(&dirent, 0, sizeof(dirent));
memcpy(dirent.filename, entry->file_name, 8);
memcpy(dirent.filename + 8, entry->extension, 3);
dirent.first_cluster = fat12_read_u16(&entry->first_cluster);
dirent.size = fat12_read_u32(&entry->file_size);
if ((entry->file_name[0] != 0xe5) && (entry->file_name[0] != 0x00))
callback(data, &dirent);
}
return 0;
}
int fat12_ls_foreach(struct fat12_partition *part, uint32_t dir_cluster, void *data, int (*callback)(void *data, const struct fat12_dirent *dirent)) {
uint32_t sector;
if (dir_cluster < 2) {
sector = part->root_offset;
uint32_t dir_entries;
uint32_t max_entries = part->root_entries;
uint32_t entries_per_sector = part->sector_size / sizeof(struct fat_directory_entry);
uint32_t loop = 0;
for (dir_entries = 0; dir_entries < max_entries; dir_entries += entries_per_sector) {
uint32_t entries_to_list = entries_per_sector;
if (max_entries - dir_entries < entries_to_list)
entries_to_list = max_entries - dir_entries;
fat12_ls_foreach_sector(part, part->root_offset + loop++, entries_to_list, data, callback);
}
}
else {
sector = dir_cluster * part->cluster_size + part->first_offset;
while (dir_cluster > 1 && dir_cluster < 0xff0) {
// dir_cluster = fat12_get_cluster(part->fd, dir_cluster);
}
}
return 0;
}
int fat12_close(struct fat12_partition *part) { int fat12_close(struct fat12_partition *part) {
if (!part) if (!part)
return -1; return -1;

View File

@ -25,22 +25,29 @@ static int make_image(const char *name, uint32_t size) {
return 0; return 0;
} }
static int list_directory(void *data, const struct fat12_dirent *dirent) {
printf("%d %d %x %d %d %s\n", dirent->ctime, dirent->mtime, dirent->file_attributes, dirent->size, dirent->first_cluster, dirent->filename);
}
int main(int argc, char **argv) { int main(int argc, char **argv) {
const char *img_name = "build/fat12-1800k.img"; // const char *img_name = "build/fat12-1800k.img";
const char *img_name = "disk-image";
int ret = 0; int ret = 0;
int fd; int fd;
struct fat12_partition *part = fat12_alloc(); struct fat12_partition *part = fat12_alloc();
ret = make_image(img_name, 1800 * 1024); // ret = make_image(img_name, 1800 * 1024);
if (ret == -1) { // if (ret == -1) {
return 1; // return 1;
} // }
if (-1 == fat12_open(part, img_name)) { if (-1 == fat12_open(part, img_name)) {
fprintf(stderr, "couldn't open fat12 on %s: %s\n", img_name, strerror(errno)); fprintf(stderr, "couldn't open fat12 on %s: %s\n", img_name, strerror(errno));
return 1; return 1;
} }
fat12_ls_foreach(part, 0, NULL, list_directory);
fat12_close(part); fat12_close(part);
fat12_free(&part); fat12_free(&part);