CoolPotOS/fs/vfs.c
2024-05-12 14:34:03 +08:00

313 lines
8.1 KiB
C

/*
* PlantsOS FileSystem Abstract Interface
* Copyright by min0911
*/
#include "../include/printf.h"
#include "../include/vfs.h"
#include "../include/common.h"
#include "../include/memory.h"
vfs_t vfsstl[26];
vfs_t vfsMount_Stl[26];
vfs_t *vfs_now;
static vfs_t *drive2fs(uint8_t drive) {
for (int i = 0; i < 26; i++) {
if (vfsMount_Stl[i].drive == toupper(drive) && vfsMount_Stl[i].flag == 1) {
return &vfsMount_Stl[i];
}
}
return NULL;
}
static vfs_t *ParsePath(char *result) {
vfs_t *vfs_result = vfs_now;
if (result[1] == ':') {
if (!(vfs_result = drive2fs(result[0]))) {
printf("Mount Drive is not found!\n");
printf("Parse Error.\n");
return NULL;
}
if (result) {
delete_char(result, 0);
delete_char(result, 0);
}
}
if (result) {
for (int i = 0; i < strlen(result); i++) {
if (result[i] == '\\') {
result[i] = '/';
}
}
}
return vfs_result;
}
static vfs_t *findSeat(vfs_t *vstl) {
for (int i = 0; i < 26; i++) {
if (vstl[i].flag == 0) {
return &vstl[i];
}
}
return NULL;
}
static vfs_t *check_disk_fs(uint8_t disk_number) {
for (int i = 0; i < 26; i++) {
if (vfsstl[i].flag == 1) {
if (vfsstl[i].Check(disk_number)) {
return &vfsstl[i];
}
}
}
return NULL;
}
static void insert_str1(char *str, char *insert_str1, int pos) {
for (int i = 0; i < strlen(insert_str1); i++) {
insert_char(str, pos + i, insert_str1[i]);
}
}
bool vfs_mount_disk(uint8_t disk_number, uint8_t drive) {
printf("Mount DISK ---- %02x\n", disk_number);
for (int i = 0; i < 26; i++) {
if (vfsMount_Stl[i].flag == 1 &&
(vfsMount_Stl[i].drive == drive ||
vfsMount_Stl[i].disk_number == disk_number)) {
return false;
}
}
vfs_t *seat = findSeat(vfsMount_Stl);
if (!seat) {
printf("can not find a seat of vfsMount_Stl(it's full)\n");
return false;
}
vfs_t *fs = check_disk_fs(disk_number);
if (!fs) {
printf("unknow file system.\n");
return false;
}
*seat = *fs;
seat->InitFs(seat, disk_number);
seat->drive = drive;
seat->disk_number = disk_number;
seat->flag = 1;
return true;
}
bool vfs_unmount_disk(uint8_t drive) {
printf("Unmount disk ---- %c\n", drive);
for (int i = 0; i < 26; i++) {
if (vfsMount_Stl[i].drive == drive && vfsMount_Stl[i].flag == 1) {
vfsMount_Stl[i].DeleteFs(&vfsMount_Stl[i]);
vfsMount_Stl[i].flag = 0;
return true;
}
}
printf("Not found the drive.\n");
return false;
}
bool vfs_readfile(char *path, char *buffer) {
char *new_path = kmalloc(strlen(path) + 1);
strcpy(new_path, path);
vfs_t *vfs = ParsePath(new_path);
if (vfs == NULL) {
kfree(new_path);
return false;
}
int result = vfs->ReadFile(vfs, new_path, buffer);
kfree(new_path);
return result;
}
bool vfs_writefile(char *path, char *buffer, int size) {
char *new_path = kmalloc(strlen(path) + 1);
strcpy(new_path, path);
vfs_t *vfs = ParsePath(new_path);
if (vfs == NULL) {
kfree(new_path);
return false;
}
int result = vfs->WriteFile(vfs, new_path, buffer, size);
kfree(new_path);
return result;
}
uint32_t vfs_filesize(char *filename) {
char *new_path = kmalloc(strlen(filename) + 1);
strcpy(new_path, filename);
vfs_t *vfs = ParsePath(new_path);
if (vfs == NULL) {
kfree(new_path);
return -1;
}
int result = vfs->FileSize(vfs, new_path); // 没找到文件统一返回-1
kfree(new_path);
return result;
}
List *vfs_listfile(char *dictpath) { // dictpath == "" 则表示当前路径
if (strcmp(dictpath, "") == 0) {
return vfs_now->ListFile(vfs_now, dictpath);
} else {
char *new_path = kmalloc(strlen(dictpath) + 1);
strcpy(new_path, dictpath);
vfs_t *vfs = ParsePath(new_path);
if (vfs == NULL) {
kfree(new_path);
return NULL;
}
List *result = vfs->ListFile(vfs, new_path);
kfree(new_path);
return result;
}
}
bool vfs_delfile(char *filename) {
char *new_path = kmalloc(strlen(filename) + 1);
strcpy(new_path, filename);
vfs_t *vfs = ParsePath(new_path);
if (vfs == NULL) {
kfree(new_path);
return false;
}
int result = vfs->DelFile(vfs, new_path);
kfree(new_path);
return result;
}
bool vfs_deldir(char *dictname) {
char *new_path = kmalloc(strlen(dictname) + 1);
strcpy(new_path, dictname);
vfs_t *vfs = ParsePath(new_path);
if (vfs == NULL) {
kfree(new_path);
return false;
}
int result = vfs->DelDict(vfs, new_path);
kfree(new_path);
return result;
}
bool vfs_createfile(char *filename) {
char *new_path = kmalloc(strlen(filename) + 1);
strcpy(new_path, filename);
vfs_t *vfs = ParsePath(new_path);
if (vfs == NULL) {
kfree(new_path);
return false;
}
int result = vfs->CreateFile(vfs, new_path);
kfree(new_path);
return result;
}
bool vfs_createdict(char *filename) {
char *new_path = kmalloc(strlen(filename) + 1);
strcpy(new_path, filename);
vfs_t *vfs = ParsePath(new_path);
if (vfs == NULL) {
kfree(new_path);
return false;
}
int result = vfs->CreateDict(vfs, new_path);
kfree(new_path);
return result;
}
bool vfs_renamefile(char *filename, char *filename_of_new) {
char *new_path = kmalloc(strlen(filename) + 1);
strcpy(new_path, filename);
vfs_t *vfs = ParsePath(new_path);
if (vfs == NULL) {
kfree(new_path);
return false;
}
int result = vfs->RenameFile(vfs, new_path, filename_of_new);
kfree(new_path);
return result;
}
bool vfs_attrib(char *filename, ftype type) {
char *new_path = kmalloc(strlen(filename) + 1);
strcpy(new_path, filename);
vfs_t *vfs = ParsePath(new_path);
if (vfs == NULL) {
kfree(new_path);
return false;
}
int result = vfs->Attrib(vfs, new_path, type);
kfree(new_path);
return result;
}
bool vfs_format(uint8_t disk_number, char *FSName) {
for (int i = 0; i < 255; i++) {
if (strcmp(vfsstl[i].FSName, FSName) == 0 && vfsstl[i].flag == 1) {
return vfsstl[i].Format(disk_number);
}
}
return false;
}
vfs_file *vfs_fileinfo(char *filename) {
char *new_path = kmalloc(strlen(filename) + 1);
strcpy(new_path, filename);
vfs_t *vfs = ParsePath(new_path);
if (vfs == NULL) {
kfree(new_path);
return false;
}
vfs_file *result = vfs->FileInfo(vfs, new_path);
kfree(new_path);
return result;
}
bool vfs_change_disk(uint8_t drive) {
if (vfs_now != NULL) {
while (FindForCount(1, vfs_now->path) != NULL) {
kfree(FindForCount(vfs_now->path->ctl->all, vfs_now->path)->val);
DeleteVal(vfs_now->path->ctl->all, vfs_now->path);
}
kfree(vfs_now->cache);
DeleteList(vfs_now->path);
kfree(vfs_now);
}
vfs_t *f;
if (!(f = drive2fs(drive))) {
return false; // 没有mount
}
vfs_now = kmalloc(sizeof(vfs_t));
memcpy(vfs_now, f, sizeof(vfs_t));
f->CopyCache(vfs_now, f);
vfs_now->path = NewList();
vfs_now->cd(vfs_now, "/");
return true;
}
void init_vfs() {
for (int i = 0; i < 26; i++) {
vfsstl[i].flag = 0;
vfsstl[i].disk_number = 0;
vfsstl[i].drive = 0;
vfsMount_Stl[i].flag = 0;
vfsMount_Stl[i].disk_number = 0;
vfsMount_Stl[i].drive = 0;
// PDEBUG("Set vfsstl[%d] & vfsMount_Stl[%d] OK.", i, i);
}
vfs_now = NULL;
}
bool vfs_register_fs(vfs_t vfs) {
printf("Register file system: %s\n", vfs.FSName);
vfs_t *seat;
seat = findSeat(vfsstl);
if (!seat) {
printf("can not find a seat of vfsstl(it's full)\n");
return false;
}
*seat = vfs;
return true;
}