Files
KatauOS/src/fs/vfs.c
T

287 lines
7.1 KiB
C

#include "../include/vfs.h"
#include "../include/stdio.h"
#include "../include/string.h"
#include "../include/paging.h"
#include "../include/liballoc.h"
l9660_fs* global_fs;
l9660_dir* root_dir;
bool read_sector_callback(l9660_fs *fs, void *buf, uint32_t sector) {
// The 'fs' parameter is not needed for our simple case, so we can ignore it.
(void)fs;
// Call your existing CD-ROM read function to read 1 sector.
// We assume the CD-ROM is the secondary master (0x170).
int result = read_cdrom(0x170, false, sector, 1, (uint16_t*)buf);
// lib9660 expects 'true' for success and 'false' for failure.
// Your read_cdrom returns 0 for success.
return (result == 0);
}
void mount_fs()
{
global_fs = malloc(sizeof(l9660_fs));
l9660_status status = l9660_openfs(global_fs, read_sector_callback);
if (status != L9660_OK) {
printf("Error opening ISO9660 filesystem!\n");
return;
}
printf("FS mounted\n");
root_dir = malloc(sizeof(l9660_dir));
status = l9660_fs_open_root(root_dir, global_fs);
if(status != L9660_OK)
{
printf("Error opening root dir\n");
return;
}
printf("root dir opened\n");
}
void list_files(l9660_dir *dir)
{
debug_log("----------CONTENTS----------");
l9660_status status;
for (;;) {
l9660_dirent *dent;
status = l9660_readdir(dir, &dent);
if (dent == NULL || status != L9660_OK) {
break; // End of directory or error
}
// Print the filename. It's not null-terminated, so use the length field.
for (int i = 0; i < dent->name_len; ++i) {
printf("%c", dent->name[i]);
}
printf("\n");
}
}
size_t vfs_read_file(l9660_file *file, uint8_t* buffer)
{
size_t total_read = 0;
l9660_status status;
for(;;) {
char buf[ISO_9660_BUFFER_LENGTH];
size_t read;
status = l9660_read(file, buf, ISO_9660_BUFFER_LENGTH, &read);
if (status != L9660_OK) {
printf("An error occurred during file read!\n");
break;
}
//check for EOF
if (read == 0)
break;
memcpy(buffer + total_read, buf, read);
total_read += read;
}
return total_read;
}
size_t vfs_read_file_length(l9660_file *file, uint8_t* buffer, size_t length)
{
size_t total_read = 0;
l9660_status status;
while(total_read < length) {
char buf[ISO_9660_BUFFER_LENGTH];
size_t to_read = (length - total_read) < ISO_9660_BUFFER_LENGTH ? (length - total_read) : ISO_9660_BUFFER_LENGTH;
size_t read = 0;
status = l9660_read(file, buf, to_read, &read);
if (status != L9660_OK) {
printf("An error occurred during file read!\n");
break;
}
//check for EOF
if (read == 0)
break;
memcpy(buffer + total_read, buf, read);
total_read += read;
}
return total_read;
}
void test_iso9660()
{
l9660_file g_test_file;
l9660_status status;
printf("Files in root directory:\n");
for (;;) {
l9660_dirent *dent;
status = l9660_readdir(root_dir, &dent);
if (dent == NULL || status != L9660_OK) {
break; // End of directory or error
}
// Print the filename. It's not null-terminated, so use the length field.
for (int i = 0; i < dent->name_len; ++i) {
printf("%c", dent->name[i]);
}
printf("\n");
}
printf("\nReading content of /TEST.TXT:\n");
// Re-open the root directory to reset its position before searching
l9660_fs_open_root(root_dir, global_fs);
l9660_dir boot_dir;
l9660_dir grub_dir;
status = l9660_opendirat(&boot_dir, root_dir, "boot");
printf("STATUS %X\n", status);
status = l9660_opendirat(&grub_dir, &boot_dir, "grub");
printf("STATUS %X\n", status);
status = l9660_openat(&g_test_file, &grub_dir, "grub.cfg");
if (status != L9660_OK) {
printf("Error opening TEST.TXT;1. Error code: ");
printf("%X\n", status); // Print the error code
printf("\n");
} else {
char file_buffer[129];
size_t bytes_read;
uint32_t total_bytes;
for (;;) {
// Read the next chunk of the file
status = l9660_read(&g_test_file, file_buffer, 128, &bytes_read);
// Check for a read error
if (status != L9660_OK) {
printf("An error occurred during file read!\n");
break;
}
// Check for End-Of-File
if (bytes_read == 0) {
break; // We're done
}
// Process the data we just read
total_bytes += bytes_read;
file_buffer[bytes_read] = '\0'; // Null-terminate the chunk
printf(file_buffer); // Print the chunk
}
printf("\n--- EOF ---\n");
printf("Total bytes read: ");
printf("0x%X\n", total_bytes);
}
}
int vfs_read_file_by_path(const char* path, uint8_t** buffer)
{
l9660_file* file = (l9660_file*)malloc(sizeof(l9660_file));
l9660_dir* dir = (l9660_dir*)malloc(sizeof(l9660_dir));
l9660_status err;
follow_path(path, file, dir);
debug_log("HEHE %s\n", path);
l9660_seek(file, L9660_SEEK_END, 0);
uint32_t file_size = l9660_tell(file);
debug_log("file_size: %X\n", file_size);
l9660_seek(file, L9660_SEEK_SET, 0);
*buffer = (uint8_t*)malloc(file_size);
debug_log("eeee\n");
size_t read;
read = vfs_read_file(file, *buffer);
free(file);
free(dir);
debug_log("bytes read: 0x%X\n", read);
return 0;
}
void follow_path(const char* path, l9660_file* file, l9660_dir* dir)
{
int pos = 0;
int start_from_root = 0;
char buf[32];
int bufpos = 0;
int isdir = 0;
memset(buf, 0, sizeof(buf));
if (path[pos] == '/')
{
start_from_root = 1;
pos++;
l9660_fs_open_root(dir, global_fs);
debug_log("start_from_root\n");
debug_log("/");
}
//printf("start_from_root: %X\n\n", start_from_root);
l9660_status status;
while(path[pos] != '\0')
{
while (path[pos] != '/' && path[pos] != '\0')
{
buf[bufpos] = path[pos];
pos++;
bufpos++;
}
buf[bufpos] = '\0'; // Null-terminate the string
bufpos = 0;
if(path[pos] != '\0')
{
isdir = 1;
debug_log("%s->", buf);//this is a directory
l9660_dir dir2;
status = l9660_opendirat(&dir2, dir, buf);
if(status != L9660_OK)
{
debug_log("FUCKFUCKFUCKFUCK BLYAAAT!!!!!\n");
return;
}
*dir = dir2;
}
else
{
isdir = 0;
debug_log("%s", buf);//this is a file
status = l9660_openat(file, dir, buf);
if(status != L9660_OK)
{
debug_log("PIZDAPIZDA BLYAAAT!!!!!\n");
return;
}
return;
}
pos++;
}
debug_log("\n");
//printf("buf: %s\n", buf);
debug_log("isdir: %X\n", isdir);
}