os3/libfat/libfat.c
Johnh Stefanelli 642385797c
[Host/KernelCopy] First implementation of KernelCopy
[LibFat] Add libfat
[Stage1] Add stage1 project
2022-10-06 21:20:29 +02:00

709 lines
No EOL
21 KiB
C

#include "libfat.h"
#define FAT_ENTRY_CLUSTER(entry) ((((os_u32)entry.start_cluster_high) << 16) + entry.start_cluster)
#define DIRECTORY_BUFFER_SIZE 32
FatDirectoryEntry directory_buffer[DIRECTORY_BUFFER_SIZE];
os_bool libfat_read_header_12(LFFileHandle handle, FatHeader_12* result) {
handle.seek(0, LIBFAT_SEEK_END, handle.user_data);
os_u32 size = handle.tell(handle.user_data);
if (size < sizeof(FatHeader_12)) {
return OS_FALSE;
}
handle.seek(0, LIBFAT_SEEK_ORIGIN, handle.user_data);
handle.read(sizeof(FatHeader_12), (void*)result, handle.user_data);
return OS_TRUE;
}
os_bool libfat_read_header_32(LFFileHandle handle, FatHeader_32* result) {
handle.seek(0, LIBFAT_SEEK_END, handle.user_data);
os_u32 size = handle.tell(handle.user_data);
if (size < sizeof(FatHeader_32)) {
return OS_FALSE;
}
handle.seek(0, LIBFAT_SEEK_ORIGIN, handle.user_data);
handle.read(sizeof(FatHeader_32), (void*)result, handle.user_data);
return OS_TRUE;
}
os_bool libfat_load_fat_cluster(LFControlBlock* fat, os_u32 target_cluster, os_bool force) {
if (fat->first_loaded_cluster > target_cluster ||
fat->first_loaded_cluster + fat->loaded_fat_cluster_amount <= target_cluster ||
force != OS_FALSE) {
os_u32 fat_size = fat->header.sectors_per_fat_32 * fat->header.base.bytes_per_sector;
os_u32 fat_offset = (fat->header.base.bytes_per_sector * fat->header.base.reserved_sectors);
fat->handle.seek(fat_offset, LIBFAT_SEEK_ORIGIN, fat->handle.user_data);
os_u32 fat_clusters = fat_size / sizeof(os_u32);
if (target_cluster >= fat_clusters) {
return OS_FALSE;
}
os_u32 base_cluster = target_cluster - (target_cluster % fat->loaded_fat_cluster_amount);
os_u32 final_offset = fat_offset + (base_cluster * sizeof(os_u32));
fat->handle.read(fat->loaded_fat_cluster_amount * sizeof(os_u32), (void*)fat->loaded_fat_segment, fat->handle.user_data);
return OS_TRUE;
}
return OS_TRUE;
}
os_u32 libfat_read_cluster(LFControlBlock* fat, os_u32 cluster) {
if(libfat_load_fat_cluster(fat, cluster, OS_FALSE) == OS_FALSE) {
return 0;
}
return fat->loaded_fat_segment[cluster - fat->first_loaded_cluster];
}
os_bool libfat_write_fat_cluster(LFControlBlock* fat, os_u32 cluster_id, os_u32 cluster_value) {
os_u32 fat_size = fat->header.sectors_per_fat_32 * fat->header.base.bytes_per_sector;
if (cluster_id < 2 || cluster_id >= fat_size / sizeof(os_u32)) {
return OS_FALSE;
}
os_u32 first_fat_offset = (fat->header.base.reserved_sectors * fat->header.base.bytes_per_sector);
os_u32 second_fat_offset = first_fat_offset + fat_size;
os_u32 fisrt_fat_cluster_offset = first_fat_offset + (cluster_id * sizeof(os_u32));
os_u32 second_fat_cluster_offset = second_fat_offset + (cluster_id * sizeof(os_u32));
fat->handle.seek(fisrt_fat_cluster_offset, LIBFAT_SEEK_ORIGIN, fat->handle.user_data);
fat->handle.write(sizeof(os_u32), (void*)&cluster_value, fat->handle.user_data);
fat->handle.seek(second_fat_cluster_offset, LIBFAT_SEEK_ORIGIN, fat->handle.user_data);
fat->handle.write(sizeof(os_u32), (void*)&cluster_value, fat->handle.user_data);
return OS_TRUE;
}
os_u32 libfat_load_cluster(LFControlBlock* fat, os_u32 cluster, void* buffer, os_u32 buffer_size, os_u32 offset_in_cluster) {
os_u32 cluster_size = fat->header.base.bytes_per_sector * fat->header.base.sectors_per_cluster;
os_u32 data_offset = (fat->header.base.reserved_sectors + (fat->header.sectors_per_fat_32 * fat->header.base.number_of_fats)) * fat->header.base.bytes_per_sector;
if (offset_in_cluster >= cluster_size) {
return 0;
}
os_u32 cluster_offset = data_offset + ((cluster - 2) * cluster_size) + offset_in_cluster;
os_u32 amount_to_read = cluster_size - offset_in_cluster > buffer_size ? buffer_size : cluster_size - offset_in_cluster;
if(!fat->handle.seek(cluster_offset, LIBFAT_SEEK_ORIGIN, fat->handle.user_data)) {
return 0;
}
os_u32 read = fat->handle.read(amount_to_read, buffer, fat->handle.user_data);
return read;
}
os_u32 libfat_write_cluster(LFControlBlock* fat, os_u32 cluster, void* buffer, os_u32 buffer_size, os_u32 offset_in_cluster) {
os_u32 cluster_size = fat->header.base.bytes_per_sector * fat->header.base.sectors_per_cluster;
os_u32 data_offset = (fat->header.base.reserved_sectors + (fat->header.sectors_per_fat_32 * fat->header.base.number_of_fats)) * fat->header.base.bytes_per_sector;
if (offset_in_cluster + buffer_size >= cluster_size) {
return 0;
}
os_u32 cluster_offset = data_offset + ((cluster - 2) * cluster_size) + offset_in_cluster;
if(fat->handle.seek(cluster_offset, LIBFAT_SEEK_ORIGIN, fat->handle.user_data) != OS_TRUE) {
return 0;
}
os_u32 written = fat->handle.write(buffer_size, buffer, fat->handle.user_data);
return written;
}
os_bool libfat_open(LFControlBlock* fat, LFDirectoryEntry* entry, LFFile* result) {
if(result == 0 || fat == 0 || entry == 0) {
return OS_FALSE;
}
if ((entry->entry.attribute & FAT_SYSTEM_BIT) != 0 ||
(entry->entry.attribute & FAT_VOLUME_BIT) != 0) {
return OS_FALSE;
}
result->fat = fat;
result->file_entry = *entry;
result->fat_cluster_size = fat->header.base.sectors_per_cluster * fat->header.base.bytes_per_sector;
result->position = 0;
result->current_cluster = FAT_ENTRY_CLUSTER(entry->entry);
result->in_cluster_position = 0;
return OS_TRUE;
}
os_bool libfat_open_directory(LFControlBlock* fat, LFDirectoryEntry* entry, LFDirectory* result) {
if (fat == 0 || result == 0) {
return OS_FALSE;
}
if (entry != 0 && (entry->entry.attribute & FAT_SUBDIRECTORY_BIT) == 0) {
return OS_FALSE;
}
result->fat = fat;
result->fat_cluster_size = fat->header.base.sectors_per_cluster * fat->header.base.bytes_per_sector;
result->current_cluster = entry == 0 ? fat->header.first_root_cluster : FAT_ENTRY_CLUSTER(entry->entry);
result->base_cluster = result->current_cluster;
result->position_in_cluster = 0;
result->done = 0;
return OS_TRUE;
}
os_bool libfat_read_directory(LFDirectory* dir, LFDirectoryEntry* entry) {
if (dir == 0 || entry == 0) {
return OS_FALSE;
}
if (dir->done == OS_TRUE) {
return OS_FALSE;
}
FatDirectoryEntry my_entry;
os_u32 read = libfat_load_cluster(dir->fat, dir->current_cluster, &my_entry, sizeof(FatDirectoryEntry), dir->position_in_cluster);
os_u32 cluster = dir->current_cluster;
os_u32 offset = dir->position_in_cluster;
dir->position_in_cluster += read;
if (dir->position_in_cluster == dir->fat_cluster_size) {
os_u32 next_cluster = libfat_read_cluster(dir->fat, dir->current_cluster);
if (next_cluster >= FAT_LAST_CLUSTER_32) {
dir->done = OS_TRUE;
}
dir->current_cluster = next_cluster;
}
if (my_entry.file_name[0] == '\0') {
dir->done = OS_TRUE;
return OS_FALSE;
}
entry->entry = my_entry;
entry->entry_cluster = cluster;
entry->entry_offset = offset;
return OS_TRUE;
}
os_u32 libfat_read(LFFile* file, void* buffer, os_u32 buffer_size) {
os_u32 read = 0;
os_bool eof = file->position >= file->file_entry.entry.file_size ? OS_TRUE : OS_FALSE;
while(read < buffer_size && eof != OS_TRUE) {
os_u32 amount_left = file->file_entry.entry.file_size - file->position;
os_u32 amount_to_read = (buffer_size - read) > amount_left ? amount_left : buffer_size - read;
os_u32 local_read;
if (file->in_cluster_position + amount_to_read >= file->fat_cluster_size) {
local_read = file->fat_cluster_size - file->in_cluster_position;
} else {
local_read = amount_to_read;
}
os_u32 r = libfat_load_cluster(file->fat, file->current_cluster, buffer, local_read, file->in_cluster_position);
read += r;
buffer = ((char*) buffer) + r;
file->position += r;
file->in_cluster_position += r;
if (file->in_cluster_position == file->fat_cluster_size) {
file->current_cluster = libfat_read_cluster(file->fat, file->current_cluster);
file->in_cluster_position = 0;
}
if (file->position == file->file_entry.entry.file_size) {
eof = OS_TRUE;
}
}
return read;
}
os_u32 libfat_tell(LFFile* file) {
if(file == 0) {
return 0;
}
return file->position;
}
os_bool libfat_init(LFFileHandle file, void* buffer, os_u32 buffer_size, LFControlBlock* result) {
if(libfat_read_header_32(file, &result->header) != OS_TRUE) {
return OS_FALSE;
}
result->handle = file;
result->loaded_fat_segment = (os_u32*)buffer;
result->loaded_fat_cluster_amount = buffer_size / sizeof(os_u32);
result->first_loaded_cluster = 0;
if(libfat_load_fat_cluster(result, 2, OS_TRUE) != OS_TRUE) {
return OS_FALSE;
}
return OS_TRUE;
}
os_bool libfat_seek(LFFile* file, os_s32 position, os_u32 direction) {
if (direction != LIBFAT_SEEK_CURRENT && direction != LIBFAT_SEEK_END && direction != LIBFAT_SEEK_ORIGIN) {
return OS_FALSE;
}
if (file == 0) {
return OS_FALSE;
}
os_u32 target = 0;
os_s32 final = 0;
os_s32 reverse = 0;
switch(direction) {
case LIBFAT_SEEK_ORIGIN:
target = (os_u32)position;
break;
case LIBFAT_SEEK_CURRENT:
final = position + file->position;
if (final < 0) {
return OS_FALSE;
}
target = (os_u32)final;
break;
case LIBFAT_SEEK_END:
reverse = file->file_entry.entry.file_size - position;
if (reverse < 0) {
return OS_FALSE;
}
target = (os_u32)reverse;
break;
}
if (target >= file->file_entry.entry.file_size) {
return OS_FALSE;
}
os_u32 cluster = FAT_ENTRY_CLUSTER(file->file_entry.entry);
os_u32 tmp_pos = 0;
while((tmp_pos + file->fat_cluster_size) <= target) {
os_u32 next_cluster = libfat_read_cluster(file->fat, cluster);
tmp_pos += file->fat_cluster_size;
cluster = next_cluster;
}
file->current_cluster = cluster;
file->in_cluster_position = target - tmp_pos;
file->position = target;
return OS_TRUE;
}
os_u32 libfat_find_free_cluster(LFControlBlock* fat) {
os_u32 cluster_id = 2;
os_u32 cluster_value = FAT_LAST_CLUSTER_32;
do {
cluster_value = libfat_read_cluster(fat, cluster_id);
if (cluster_value != 0) {
cluster_id++;
}
if (cluster_id >= (fat->header.sectors_per_fat_32 * fat->header.base.bytes_per_sector) / sizeof(os_u32)) {
return 0;
}
} while(cluster_value != 0);
return cluster_id;
}
os_bool libfat_fsinfo_update(LFControlBlock* fat) {
os_u32 fsinfo_offset = fat->header.fsinfo_sector * fat->header.base.bytes_per_sector;
if(fat->handle.seek(fsinfo_offset, LIBFAT_SEEK_ORIGIN, fat->handle.user_data) != OS_TRUE) {
return OS_FALSE;
}
os_u32 sig = 0;
os_u32 read = fat->handle.read(sizeof(os_u32), (void*)&sig, fat->handle.user_data);
if (read != sizeof(os_u32) || sig != FAT_FSINFO_SIG_0) {
return OS_FALSE;
}
if(fat->handle.seek(fsinfo_offset + 484, LIBFAT_SEEK_ORIGIN, fat->handle.user_data) != OS_TRUE) {
return OS_FALSE;
}
read = fat->handle.read(sizeof(os_u32), (void*)&sig, fat->handle.user_data);
if (read != sizeof(os_u32) || sig != FAT_FSINFO_SIG_1) {
return OS_FALSE;
}
os_u32 free_clusters = 0;
read = fat->handle.read(sizeof(os_u32), (void*)&free_clusters, fat->handle.user_data);
if (read != sizeof(os_u32)) {
return OS_FALSE;
}
os_u32 next_free_cluster = 0;
read = fat->handle.read(sizeof(os_u32), (void*)&next_free_cluster, fat->handle.user_data);
if (read != sizeof(os_u32)) {
return OS_FALSE;
}
if (free_clusters != 0xffffffff) {
free_clusters--;
if(fat->handle.seek(fsinfo_offset + 488, LIBFAT_SEEK_ORIGIN, fat->handle.user_data) == OS_TRUE) {
fat->handle.write(sizeof(os_u32), (void*)&free_clusters, fat->handle.user_data);
}
}
if (next_free_cluster != 0xffffffff) {
next_free_cluster = libfat_find_free_cluster(fat);
if (next_free_cluster < 2) {
next_free_cluster = 0xffffffff;
}
if (fat->handle.seek(fsinfo_offset + 492, LIBFAT_SEEK_ORIGIN, fat->handle.user_data) == OS_TRUE) {
fat->handle.write(sizeof(os_u32), (void*)&next_free_cluster, fat->handle.user_data);
}
}
return OS_TRUE;
}
os_bool libfat_fsinfo_free(LFControlBlock* fat, os_u32 freed_cluster) {
os_u32 fsinfo_offset = fat->header.fsinfo_sector * fat->header.base.bytes_per_sector;
if(fat->handle.seek(fsinfo_offset, LIBFAT_SEEK_ORIGIN, fat->handle.user_data) != OS_TRUE) {
return OS_FALSE;
}
os_u32 sig = 0;
os_u32 read = fat->handle.read(sizeof(os_u32), (void*)&sig, fat->handle.user_data);
if (read != sizeof(os_u32) || sig != FAT_FSINFO_SIG_0) {
return OS_FALSE;
}
if(fat->handle.seek(fsinfo_offset + 484, LIBFAT_SEEK_ORIGIN, fat->handle.user_data) != OS_TRUE) {
return OS_FALSE;
}
read = fat->handle.read(sizeof(os_u32), (void*)&sig, fat->handle.user_data);
if (read != sizeof(os_u32) || sig != FAT_FSINFO_SIG_1) {
return OS_FALSE;
}
os_u32 free_clusters = 0;
read = fat->handle.read(sizeof(os_u32), (void*)&free_clusters, fat->handle.user_data);
if (read != sizeof(os_u32)) {
return OS_FALSE;
}
os_u32 next_free_cluster = 0;
read = fat->handle.read(sizeof(os_u32), (void*)&next_free_cluster, fat->handle.user_data);
if (read != sizeof(os_u32)) {
return OS_FALSE;
}
if (free_clusters != 0xffffffff) {
free_clusters++;
if(fat->handle.seek(fsinfo_offset + 488, LIBFAT_SEEK_ORIGIN, fat->handle.user_data) == OS_TRUE) {
fat->handle.write(sizeof(os_u32), (void*)&free_clusters, fat->handle.user_data);
}
}
if (next_free_cluster != 0xffffffff && freed_cluster < next_free_cluster) {
next_free_cluster = libfat_find_free_cluster(fat);
if (next_free_cluster < 2) {
next_free_cluster = 0xffffffff;
}
if (fat->handle.seek(fsinfo_offset + 492, LIBFAT_SEEK_ORIGIN, fat->handle.user_data) == OS_TRUE) {
fat->handle.write(sizeof(os_u32), (void*)&next_free_cluster, fat->handle.user_data);
}
}
return OS_TRUE;
}
os_bool libfat_truncate(LFControlBlock* fat, LFDirectoryEntry* entry) {
if (fat == 0 || entry == 0) {
return OS_FALSE;
}
if ((entry->entry.attribute & FAT_SUBDIRECTORY_BIT) != 0) {
return OS_FALSE; //Disable truncating subdirectories
}
entry->entry.file_size = 0;
os_u32 written = libfat_write_cluster(fat, entry->entry_cluster, &entry->entry, sizeof(FatDirectoryEntry), entry->entry_offset);
if (written != sizeof(FatDirectoryEntry)) {
return OS_FALSE;
}
os_u32 cluster = libfat_read_cluster(fat, FAT_ENTRY_CLUSTER(entry->entry));
libfat_write_fat_cluster(fat, FAT_ENTRY_CLUSTER(entry->entry), FAT_LAST_CLUSTER_32_2);
while(cluster < FAT_LAST_CLUSTER_32) {
os_u32 next_cluster = libfat_read_cluster(fat, cluster);
libfat_write_fat_cluster(fat, cluster, 0);
libfat_fsinfo_free(fat, cluster);
cluster = next_cluster;
}
return OS_TRUE;
}
os_u32 libfat_add_cluster_to_chain(LFControlBlock* fat, os_u32 last_cluster_id) {
os_u32 cluster_value;
do {
cluster_value = libfat_read_cluster(fat, last_cluster_id);
if(cluster_value == 0) {
return 0;
}
} while(cluster_value < FAT_LAST_CLUSTER_32);
os_u32 free_cluster = libfat_find_free_cluster(fat);
if (free_cluster == 0) {
return 0;
}
if(libfat_write_fat_cluster(fat, last_cluster_id, free_cluster) != OS_TRUE) {
return 0;
}
if(libfat_write_fat_cluster(fat, free_cluster, FAT_LAST_CLUSTER_32_2) != OS_TRUE) {
return 0;
}
libfat_fsinfo_update(fat);
return free_cluster;
}
os_bool libfat_add_entry_to_directory(LFControlBlock* fat, LFDirectoryEntry* parent, FatDirectoryEntry* entry, LFDirectoryEntry* result) {
os_u32 cluster = fat->header.first_root_cluster;
if (parent != 0) {
cluster = FAT_ENTRY_CLUSTER(parent->entry);
}
os_u32 cluster_offset = 0;
os_u32 next_cluster = libfat_read_cluster(fat, cluster);
FatDirectoryEntry local_entry;
do {
os_u32 read = libfat_load_cluster(fat, cluster, (void*)&local_entry, sizeof(FatDirectoryEntry), cluster_offset);
if (local_entry.file_name[0] == '\0') {
break;
}
cluster_offset += read;
if (cluster_offset >= fat->header.base.sectors_per_cluster * fat->header.base.bytes_per_sector) {
cluster_offset = 0;
if (next_cluster >= FAT_LAST_CLUSTER_32) {
next_cluster = libfat_add_cluster_to_chain(fat, next_cluster);
if (next_cluster == 0) {
//Invalid end cluster or no more available clusters
return OS_FALSE;
}
}
cluster = next_cluster;
next_cluster = libfat_read_cluster(fat, cluster);
break;
}
} while(local_entry.file_name[0] != '\0');
if(libfat_write_cluster(fat, cluster, (void*)entry, sizeof(FatDirectoryEntry), cluster_offset) == 0) {
return OS_FALSE; //TODO: Maybe undo added cluster
}
result->entry_cluster = cluster;
result->entry_offset = cluster_offset;
result->entry = *entry;
cluster_offset += sizeof(FatDirectoryEntry);
if (cluster_offset >= fat->header.base.bytes_per_sector * fat->header.base.sectors_per_cluster) {
cluster = libfat_add_cluster_to_chain(fat, cluster);
cluster_offset = 0;
}
char buffer[sizeof(FatDirectoryEntry)];
for(int i = 0; i < sizeof(FatDirectoryEntry); i++) {
buffer[i] = '\0';
}
libfat_write_cluster(fat, cluster, (void*)buffer, sizeof(FatDirectoryEntry), cluster_offset);
return OS_TRUE;
}
os_bool libfat_create(LFControlBlock* fat, LFDirectoryEntry* parent_entry, os_s8* name, os_bool directory, LFDirectoryEntry* result) {
FatDirectoryEntry new_entry;
for(int i = 0; i < 8; i++) {
new_entry.file_name[i] = name[i];
}
for(int i = 0; i < 3; i++) {
new_entry.extension[i] = name[8 + i];
}
new_entry.attribute = directory != OS_FALSE ? FAT_SUBDIRECTORY_BIT : 0;
new_entry.date = 0;
for(int i = 0; i < 8; i++) {
new_entry.reserved[i] = 0;
}
new_entry.time = 0;
new_entry.file_size = 0;
os_u32 cluster = libfat_find_free_cluster(fat);
if (cluster < 2) {
return OS_FALSE;
}
new_entry.start_cluster = (os_u16) cluster;
new_entry.start_cluster_high = (os_u16) (cluster >> 16);
if (libfat_write_fat_cluster(fat, cluster, FAT_LAST_CLUSTER_32_2) != OS_TRUE) {
return OS_FALSE;
}
if(libfat_add_entry_to_directory(fat, parent_entry, &new_entry, result) != OS_TRUE) {
libfat_write_fat_cluster(fat, cluster, 0);
return OS_FALSE;
}
libfat_fsinfo_update(fat);
return OS_TRUE;
}
os_u32 libfat_write(LFFile* f, void* buffer, os_u32 buffer_size) {
if (f == 0 || buffer == 0 || buffer_size == 0) {
return 0;
}
os_u32 start_position = f->position;
os_u32 written = 0;
while (buffer_size > 0) {
os_u32 amount = f->fat_cluster_size - f->in_cluster_position;
if (amount > buffer_size) {
amount = buffer_size;
}
os_u32 w = libfat_write_cluster(f->fat, f->current_cluster, buffer, amount, f->in_cluster_position);
written += w;
f->position += w;
f->in_cluster_position += w;
buffer = ((char*)buffer) + w;
buffer_size -= w;
if (f->in_cluster_position >= f->fat_cluster_size) {
f->in_cluster_position = 0;
os_u32 next = libfat_read_cluster(f->fat, f->current_cluster);
if (next >= FAT_LAST_CLUSTER_32_2) {
next = libfat_add_cluster_to_chain(f->fat, next);
}
f->current_cluster = next;
}
}
if(f->position > f->file_entry.entry.file_size) {
f->file_entry.entry.file_size = f->position;
libfat_write_cluster(f->fat, f->file_entry.entry_cluster, (void*)&f->file_entry.entry, sizeof(FatDirectoryEntry), f->file_entry.entry_offset);
}
return written;
}
os_u32 libfat_get_true_entry_offset(LFControlBlock* fat, LFDirectoryEntry* entry) {
if (fat == 0 || entry == 0) {
return 0;
}
os_u32 cluster_size = fat->header.base.bytes_per_sector * fat->header.base.sectors_per_cluster;
os_u32 data_offset = (fat->header.base.reserved_sectors + (fat->header.sectors_per_fat_32 * fat->header.base.number_of_fats)) * fat->header.base.bytes_per_sector;
return data_offset + (cluster_size * FAT_ENTRY_CLUSTER(entry->entry) - 2);
}
os_bool libfat_test_mbr(LFFileHandle* mbr) {
if (mbr == 0) {
return OS_FALSE;
}
if(mbr->seek(0, LIBFAT_SEEK_ORIGIN, mbr->user_data) != OS_TRUE) {
return OS_FALSE;
}
char buffer[6];
os_u32 read = mbr->read(6, buffer, mbr->user_data);
if (read < 6) {
return OS_FALSE;
}
return (buffer[2] != 0x49 && buffer[3] == 0x49) ? OS_TRUE : OS_FALSE;
}
/*
void libfat_test(LFFileHandle handle, PrintRoutine print, PrintNumber printNumber) {
LFControlBlock cb;
if (libfat_init(handle, loaded_fat_segment, 512 * sizeof(os_u32), &cb) != OS_TRUE) {
print("Failed to init FAT.", 0);
return;
}
LFDirectory dir;
if (libfat_open_directory(&cb, 0, &dir) != OS_TRUE) {
print("Failecd to open directory.", 0);
return;
}
os_bool any = OS_FALSE;
LFDirectoryEntry entry;
while(libfat_read_directory(&dir, &entry) == OS_TRUE) {
if ((entry.entry.attribute & (os_s8)FAT_HIDDEN_BIT) != 0 ||
(entry.entry.attribute & (os_s8)FAT_VOLUME_BIT) != 0 ||
(entry.entry.attribute & (os_s8)FAT_SYSTEM_BIT) != 0) {
continue;
}
any = OS_TRUE;
print("Entry name: ", 0);
print(entry.entry.file_name, 11);
os_u32 cluster = FAT_ENTRY_CLUSTER(entry.entry);
print("Cluster: ", 0);
printNumber(cluster);
print("Size: ", 0);
printNumber(entry.entry.file_size);
os_u32 effective_size = entry.entry.file_size > 512 ? 512 : entry.entry.file_size;
if(effective_size > 0) {
LFFile f;
if (libfat_open(&cb, &entry, &f) == OS_TRUE) {
char buffer[512];
os_u32 amount = libfat_read(&f, buffer, 512);
print("Content: ", 0);
print(buffer, amount);
}
}
print("--------", 0);
}
if(any == OS_FALSE) {
LFDirectoryEntry created_file;
libfat_create(&cb, 0, "TEST TXT", OS_FALSE, &created_file);
print("Added file 'test.txt'", 0);
LFFile new_file;
if(libfat_open(&cb, &created_file, &new_file) != OS_TRUE) {
print("Failed to open new file", 0);
return;
}
char* data = "test";
libfat_write(&new_file, data, 5);
}
}
*/