CoolPotOS/fs/vfs.c
2024-05-18 23:44:25 +08:00

414 lines
10 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("[FileSystem]: Unknown 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_change_path(char *dictName) {
char *buf = kmalloc(strlen(dictName) + 1);
char *r = buf;
memcpy(buf, dictName, strlen(dictName) + 1);
int i = 0;
if (buf[i] == '/' || buf[i] == '\\') {
if (!vfs_now->cd(vfs_now, "/")) {
kfree(r);
return false;
}
i++;
buf++;
}
for (;; i++) {
if (buf[i] == '/' || buf[i] == '\\') {
buf[i] = 0;
if (!vfs_now->cd(vfs_now, buf)) {
kfree(r);
return false;
}
buf += strlen(buf) + 1;
}
if (buf[i] == 0) {
if (!vfs_now->cd(vfs_now, buf)) {
kfree(r);
return false;
}
break;
}
}
kfree(r);
return true;
}
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);
memclean(new_path, 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);
memclean(new_path,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;
}
vfs_file *get_cur_file(char* filename){
vfs_file *file = NULL;
List *ls = vfs_listfile("");
strtoupper(filename);
for (int i = 1; FindForCount(i, ls) != NULL; i++) {
vfs_file *d = (vfs_file *) FindForCount(i, ls)->val;
if(strcmp(d->name, filename) == 0){
file = d;
break;
}
kfree(d);
}
DeleteList(ls);
kfree(ls);
return file;
}
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 vfs_getPath(char *buffer) {
char *path;
List *l;
buffer[0] = 0;
insert_char(buffer, 0, vfs_now->drive);
insert_char(buffer, 1, ':');
insert_char(buffer, 2, '\\');
int pos = strlen(buffer);
for (int i = 1; FindForCount(i, vfs_now->path) != NULL; i++) {
l = FindForCount(i, vfs_now->path);
path = (char *)l->val;
insert_str(buffer, path, pos);
pos += strlen(path);
insert_char(buffer, pos, '\\');
pos++;
}
delete_char(buffer, pos - 1);
}
void vfs_getPath_no_drive(char *buffer) {
char *path;
List *l;
buffer[0] = 0;
int pos = strlen(buffer);
int i;
for (i = 1; FindForCount(i, vfs_now->path) != NULL; i++) {
l = FindForCount(i, vfs_now->path);
path = (char *)l->val;
insert_char(buffer, pos, '/');
pos++;
insert_str(buffer, path, pos);
pos += strlen(path);
}
if (i == 1) {
insert_char(buffer, 0, '/');
}
}
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;
}