fat12: add ls_callback function
Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
parent
c4c5f706b0
commit
03e268f710
@ -4,16 +4,28 @@
|
||||
#include <stdint.h>
|
||||
|
||||
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);
|
||||
int fat12_open(struct fat12_partition *part, const char *filename);
|
||||
int fat12_close(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);
|
||||
uint8_t fat12_read_u8(void *ptr);
|
||||
void fat12_write_u16(void *ptr, uint16_t val);
|
||||
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);
|
||||
uint32_t fat12_get_cluster(void *fat, uint32_t cluster);
|
||||
|
||||
|
66
src/fat12.c
66
src/fat12.c
@ -50,6 +50,22 @@ uint16_t fat12_read_u16(void *ptr) {
|
||||
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) {
|
||||
uint32_t offset = (cluster * 3) / 2;
|
||||
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_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);
|
||||
|
||||
@ -141,6 +160,53 @@ int fat12_open(struct fat12_partition *part, const char *filename) {
|
||||
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) {
|
||||
if (!part)
|
||||
return -1;
|
||||
|
@ -25,22 +25,29 @@ static int make_image(const char *name, uint32_t size) {
|
||||
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) {
|
||||
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 fd;
|
||||
struct fat12_partition *part = fat12_alloc();
|
||||
|
||||
ret = make_image(img_name, 1800 * 1024);
|
||||
if (ret == -1) {
|
||||
return 1;
|
||||
}
|
||||
// ret = make_image(img_name, 1800 * 1024);
|
||||
// if (ret == -1) {
|
||||
// return 1;
|
||||
// }
|
||||
|
||||
if (-1 == fat12_open(part, img_name)) {
|
||||
fprintf(stderr, "couldn't open fat12 on %s: %s\n", img_name, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
fat12_ls_foreach(part, 0, NULL, list_directory);
|
||||
|
||||
fat12_close(part);
|
||||
fat12_free(&part);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user