[MBR] add pos-jump signature (for future checks)
[LIBFAT] Add file creation and writing capabilities
This commit is contained in:
parent
58de4d6c32
commit
ad55abdeb0
4 changed files with 381 additions and 30 deletions
|
|
@ -80,7 +80,7 @@ int main(int argc, char** argv) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
FILE* f = fopen(argv[1], "rb");
|
||||
FILE* f = fopen(argv[1], "rb+");
|
||||
|
||||
FileHandle h;
|
||||
h.read = readRoutine;
|
||||
|
|
|
|||
|
|
@ -89,6 +89,10 @@ OS_PACK_END;
|
|||
#define FAT_ARCHIVE_BIT 32
|
||||
|
||||
#define FAT_LAST_CLUSTER_32 0xFFFFFFF8
|
||||
#define FAT_LAST_CLUSTER_32_2 0xFFFFFFFF
|
||||
|
||||
#define FAT_FSINFO_SIG_0 0x41615252
|
||||
#define FAT_FSINFO_SIG_1 0x61417272
|
||||
|
||||
OS_PACK_START
|
||||
struct _FatDirectoryEntry {
|
||||
|
|
@ -108,6 +112,12 @@ typedef struct _FatDirectoryEntry FatDirectoryEntry;
|
|||
|
||||
typedef struct _FatHeader_32 FatHeader_32;
|
||||
|
||||
typedef struct _LibFatDirectoryEntry {
|
||||
FatDirectoryEntry entry;
|
||||
os_u32 entry_cluster;
|
||||
os_u32 entry_offset;
|
||||
} LibFatDirectoryEntry;
|
||||
|
||||
typedef struct _FatControlBlock {
|
||||
FileHandle handle;
|
||||
FatHeader_32 header;
|
||||
|
|
@ -118,11 +128,10 @@ typedef struct _FatControlBlock {
|
|||
|
||||
typedef struct _LibFatFile {
|
||||
FatControlBlock* fat;
|
||||
FatDirectoryEntry file_entry;
|
||||
LibFatDirectoryEntry file_entry;
|
||||
os_u32 current_cluster;
|
||||
os_u32 position;
|
||||
os_u32 in_cluster_position;
|
||||
os_u32 fat_data_offset;
|
||||
os_u32 fat_cluster_size;
|
||||
} LibFatFile;
|
||||
|
||||
|
|
@ -137,11 +146,16 @@ typedef struct _LibFatDirectory {
|
|||
|
||||
|
||||
extern os_bool libfat_init(FileHandle handle, void* buffer, os_u32 buffer_size, FatControlBlock* result);
|
||||
extern os_bool libfat_open_read(FatControlBlock* fat, FatDirectoryEntry* entry, LibFatFile* result);
|
||||
extern os_bool libfat_open(FatControlBlock* fat, LibFatDirectoryEntry* entry, LibFatFile* result);
|
||||
extern os_u32 libfat_read(LibFatFile* file, void* buffer, os_u32 buffer_size);
|
||||
extern os_u32 libfat_write(LibFatFile* file, void* biffer, os_u32 buffer_size);
|
||||
extern os_bool libfat_seek(LibFatFile* file, os_s32 position, os_u32 direction);
|
||||
extern os_u32 libfat_tell(LibFatFile* file);
|
||||
|
||||
extern os_bool libfat_open_directory(FatControlBlock* fat, FatDirectoryEntry* entry, LibFatDirectory* result);
|
||||
extern void libfat_test(FileHandle image_file, PrintRoutine print, PrintNumber rintNumber);
|
||||
extern os_bool libfat_create(FatControlBlock* fat, LibFatDirectoryEntry* parent_entry, os_s8* name, os_bool directory, LibFatDirectoryEntry* result);
|
||||
|
||||
extern os_bool libfat_open_directory(FatControlBlock* fat, LibFatDirectoryEntry* entry, LibFatDirectory* result);
|
||||
extern os_bool libfat_read_directory(LibFatDirectory* dir, LibFatDirectoryEntry* entry);
|
||||
extern void libfat_test(FileHandle handle, PrintRoutine print, PrintNumber printNumber);
|
||||
|
||||
#endif //!__OS3_LIBFAT_H
|
||||
381
libfat/libfat.c
381
libfat/libfat.c
|
|
@ -50,7 +50,7 @@ os_bool libfat_load_fat_cluster(FatControlBlock* fat, os_u32 target_cluster, os_
|
|||
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_size;
|
||||
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);
|
||||
|
|
@ -77,6 +77,28 @@ os_u32 libfat_read_cluster(FatControlBlock* fat, os_u32 cluster) {
|
|||
return fat->loaded_fat_segment[cluster - fat->first_loaded_cluster];
|
||||
}
|
||||
|
||||
|
||||
os_bool libfat_write_fat_cluster(FatControlBlock* 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(FatControlBlock* 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;
|
||||
|
|
@ -98,39 +120,54 @@ os_u32 libfat_load_cluster(FatControlBlock* fat, os_u32 cluster, void* buffer, o
|
|||
|
||||
}
|
||||
|
||||
os_bool libfat_open_read(FatControlBlock* fat, FatDirectoryEntry* entry, LibFatFile* result) {
|
||||
os_u32 libfat_write_cluster(FatControlBlock* 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(FatControlBlock* fat, LibFatDirectoryEntry* entry, LibFatFile* result) {
|
||||
if(result == 0 || fat == 0 || entry == 0) {
|
||||
return OS_FALSE;
|
||||
}
|
||||
|
||||
if ((entry->attribute & FAT_SYSTEM_BIT) != 0 ||
|
||||
(entry->attribute & FAT_VOLUME_BIT) != 0) {
|
||||
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->fat_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;
|
||||
result->position = 0;
|
||||
result->current_cluster = (((os_u32)entry->start_cluster_high) << 16) + entry->start_cluster;
|
||||
result->current_cluster = (((os_u32)entry->entry.start_cluster_high) << 16) + entry->entry.start_cluster;
|
||||
result->in_cluster_position = 0;
|
||||
|
||||
return OS_TRUE;
|
||||
}
|
||||
|
||||
os_bool libfat_open_directory(FatControlBlock* fat, FatDirectoryEntry* entry, LibFatDirectory* result) {
|
||||
os_bool libfat_open_directory(FatControlBlock* fat, LibFatDirectoryEntry* entry, LibFatDirectory* result) {
|
||||
if (fat == 0 || result == 0) {
|
||||
return OS_FALSE;
|
||||
}
|
||||
|
||||
if (entry != 0 && (entry->attribute & FAT_SUBDIRECTORY_BIT) == 0) {
|
||||
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 : (((os_u32)entry->start_cluster_high) << 16) + entry->start_cluster;
|
||||
result->current_cluster = entry == 0 ? fat->header.first_root_cluster : (((os_u32)entry->entry.start_cluster_high) << 16) + entry->entry.start_cluster;
|
||||
result->base_cluster = result->current_cluster;
|
||||
result->position_in_cluster = 0;
|
||||
result->done = 0;
|
||||
|
|
@ -138,7 +175,7 @@ os_bool libfat_open_directory(FatControlBlock* fat, FatDirectoryEntry* entry, Li
|
|||
return OS_TRUE;
|
||||
}
|
||||
|
||||
os_bool libfat_read_directory(LibFatDirectory* dir, FatDirectoryEntry* entry) {
|
||||
os_bool libfat_read_directory(LibFatDirectory* dir, LibFatDirectoryEntry* entry) {
|
||||
if (dir == 0 || entry == 0) {
|
||||
return OS_FALSE;
|
||||
}
|
||||
|
|
@ -149,12 +186,15 @@ os_bool libfat_read_directory(LibFatDirectory* dir, FatDirectoryEntry* entry) {
|
|||
|
||||
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') {
|
||||
|
|
@ -162,15 +202,17 @@ os_bool libfat_read_directory(LibFatDirectory* dir, FatDirectoryEntry* entry) {
|
|||
return OS_FALSE;
|
||||
}
|
||||
|
||||
*entry = my_entry;
|
||||
entry->entry = my_entry;
|
||||
entry->entry_cluster = cluster;
|
||||
entry->entry_offset = offset;
|
||||
return OS_TRUE;
|
||||
}
|
||||
|
||||
os_u32 libfat_read(LibFatFile* file, void* buffer, os_u32 buffer_size) {
|
||||
os_u32 read = 0;
|
||||
os_bool eof = file->position >= file->file_entry.file_size ? OS_TRUE : OS_FALSE;
|
||||
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.file_size - file->position;
|
||||
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;
|
||||
|
|
@ -191,7 +233,7 @@ os_u32 libfat_read(LibFatFile* file, void* buffer, os_u32 buffer_size) {
|
|||
file->in_cluster_position = 0;
|
||||
}
|
||||
|
||||
if (file->position == file->file_entry.file_size) {
|
||||
if (file->position == file->file_entry.entry.file_size) {
|
||||
eof = OS_TRUE;
|
||||
}
|
||||
}
|
||||
|
|
@ -224,6 +266,282 @@ os_bool libfat_init(FileHandle file, void* buffer, os_u32 buffer_size, FatContro
|
|||
return OS_TRUE;
|
||||
}
|
||||
|
||||
os_bool libfat_seek(LibFatFile* 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 = (((os_u32)file->file_entry.entry.start_cluster_high) << 16) + file->file_entry.entry.start_cluster;
|
||||
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(FatControlBlock* 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(FatControlBlock* 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_u32 libfat_add_cluster_to_chain(FatControlBlock* 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(FatControlBlock* fat, LibFatDirectoryEntry* parent, FatDirectoryEntry* entry, LibFatDirectoryEntry* result) {
|
||||
os_u32 cluster = fat->header.first_root_cluster;
|
||||
if (parent != 0) {
|
||||
cluster = (((os_u32)parent->entry.start_cluster_high) << 16) + parent->entry.start_cluster;
|
||||
}
|
||||
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(FatControlBlock* fat, LibFatDirectoryEntry* parent_entry, os_s8* name, os_bool directory, LibFatDirectoryEntry* 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(LibFatFile* 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 += 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;
|
||||
}
|
||||
|
||||
void libfat_test(FileHandle handle, PrintRoutine print, PrintNumber printNumber) {
|
||||
FatControlBlock cb;
|
||||
if (libfat_init(handle, loaded_fat_segment, 512 * sizeof(os_u32), &cb) != OS_TRUE) {
|
||||
|
|
@ -237,29 +555,31 @@ void libfat_test(FileHandle handle, PrintRoutine print, PrintNumber printNumber)
|
|||
return;
|
||||
}
|
||||
|
||||
FatDirectoryEntry entry;
|
||||
os_bool any = OS_FALSE;
|
||||
LibFatDirectoryEntry entry;
|
||||
while(libfat_read_directory(&dir, &entry) == OS_TRUE) {
|
||||
if ((entry.attribute & (os_s8)FAT_HIDDEN_BIT) != 0 ||
|
||||
(entry.attribute & (os_s8)FAT_VOLUME_BIT) != 0 ||
|
||||
(entry.attribute & (os_s8)FAT_SYSTEM_BIT) != 0) {
|
||||
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.file_name, 11);
|
||||
print(entry.entry.file_name, 11);
|
||||
|
||||
os_u32 cluster = (((os_u32)entry.start_cluster_high) << 16) + entry.start_cluster;
|
||||
os_u32 cluster = (((os_u32)entry.entry.start_cluster_high) << 16) + entry.entry.start_cluster;
|
||||
|
||||
print("Cluster: ", 0);
|
||||
printNumber(cluster);
|
||||
|
||||
print("Size: ", 0);
|
||||
printNumber(entry.file_size);
|
||||
printNumber(entry.entry.file_size);
|
||||
|
||||
os_u32 effective_size = entry.file_size > 512 ? 512 : entry.file_size;
|
||||
os_u32 effective_size = entry.entry.file_size > 512 ? 512 : entry.entry.file_size;
|
||||
if(effective_size > 0) {
|
||||
LibFatFile f;
|
||||
if (libfat_open_read(&cb, &entry, &f) == OS_TRUE) {
|
||||
if (libfat_open(&cb, &entry, &f) == OS_TRUE) {
|
||||
char buffer[512];
|
||||
os_u32 amount = libfat_read(&f, buffer, 512);
|
||||
print("Content: ", 0);
|
||||
|
|
@ -269,4 +589,19 @@ void libfat_test(FileHandle handle, PrintRoutine print, PrintNumber printNumber)
|
|||
|
||||
print("--------", 0);
|
||||
}
|
||||
|
||||
if(any == OS_FALSE) {
|
||||
LibFatDirectoryEntry created_file;
|
||||
libfat_create(&cb, 0, "TEST TXT", OS_FALSE, &created_file);
|
||||
print("Added file 'test.txt'", 0);
|
||||
|
||||
LibFatFile 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,9 @@ _main:
|
|||
JMP entry
|
||||
; FAT32 Header.
|
||||
global fat_header
|
||||
fat_header: times 87 db 0
|
||||
fat_header:
|
||||
dw 0x4949
|
||||
times 85 db 0
|
||||
|
||||
; function READ_SECTORS_EXTENDED: Read sectors from disk
|
||||
; Uses INT 13h AH=42h from: http://www.ctyme.com/intr/rb-0708.htm
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue