414 lines
10 KiB
C
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;
|
|
} |