327 lines
9.7 KiB
C
327 lines
9.7 KiB
C
|
#include "../include/fat16.h"
|
|||
|
#include "../include/memory.h"
|
|||
|
#include "../include/disk.h"
|
|||
|
|
|||
|
void read_root_dir_sector1(struct File *root_entries) {
|
|||
|
read_disk(SECTOR_NUM_OF_ROOT_DIR_START, 1, (unsigned int) root_entries);
|
|||
|
}
|
|||
|
|
|||
|
void save_root_dir_sector1(struct File *root_entries) {
|
|||
|
write_disk(SECTOR_NUM_OF_ROOT_DIR_START, 1, (unsigned int) root_entries);
|
|||
|
}
|
|||
|
|
|||
|
void read_one_cluster(unsigned short clustno, unsigned int memory_addrress) {
|
|||
|
read_disk(clustno + SECTOR_CLUSTER_BALANCE, 1, memory_addrress);
|
|||
|
}
|
|||
|
|
|||
|
int read_root_dir(struct File *file_infos) {
|
|||
|
struct File *root_entries = (struct File *) kmalloc(SECTOR_SIZE);
|
|||
|
read_root_dir_sector1(root_entries);
|
|||
|
int n = 0; // 记录文件数
|
|||
|
for (int i = 0; i < MAX_FILE_NUM; i++) {
|
|||
|
if (root_entries[i].name[0] == 0) {
|
|||
|
break;
|
|||
|
}
|
|||
|
if (root_entries[i].name[0] != 0xe5) {
|
|||
|
file_infos[n] = root_entries[i];
|
|||
|
n++;
|
|||
|
}
|
|||
|
}
|
|||
|
kfree(root_entries);
|
|||
|
return n;
|
|||
|
}
|
|||
|
|
|||
|
void get_fat1(unsigned short *fat1) {
|
|||
|
read_disk(SECTOR_NUM_OF_FAT1_START, FAT1_SECTORS, (unsigned int) fat1); // 将FAT1全部读取到内存中。
|
|||
|
}
|
|||
|
|
|||
|
void save_fat1(unsigned short *fat1) {
|
|||
|
write_disk(SECTOR_NUM_OF_FAT1_START, FAT1_SECTORS, (unsigned int) fat1); // 将FAT1全部写回到内存中。
|
|||
|
}
|
|||
|
|
|||
|
void get_file_all_clustnos(unsigned short first_clustno, unsigned short *clustnos) {
|
|||
|
unsigned short *fat1 = kmalloc(FAT1_SECTORS * SECTOR_SIZE);
|
|||
|
get_fat1(fat1);
|
|||
|
*clustnos = first_clustno;
|
|||
|
while (1) {
|
|||
|
unsigned short clustno = *(fat1 + *clustnos);
|
|||
|
clustnos++;
|
|||
|
*clustnos = clustno;
|
|||
|
if (clustno >= 0xfff8) // 大于等于0xfff8表示文件的最后一个簇
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
kfree(fat1);
|
|||
|
}
|
|||
|
|
|||
|
void read_file(struct File *file, void *file_addr) {
|
|||
|
if (file->size == 0) {
|
|||
|
return;
|
|||
|
}
|
|||
|
int cluster_count = (file->size + 511) / 512;
|
|||
|
unsigned short *clustnos = kmalloc(cluster_count * 2);
|
|||
|
get_file_all_clustnos(file->clustno, clustnos);
|
|||
|
for (int i = 0; i < cluster_count; i++) {
|
|||
|
read_one_cluster(clustnos[i], (unsigned int) file_addr);
|
|||
|
file_addr += 512;
|
|||
|
}
|
|||
|
kfree(clustnos);
|
|||
|
}
|
|||
|
|
|||
|
void check_name_or_ext(char *str, int len) {
|
|||
|
for (int i = 0; i < len; i++) {
|
|||
|
if (str[i] == 0) {
|
|||
|
str[i] = ' ';
|
|||
|
} else if ('a' <= str[i] && str[i] <= 'z') {
|
|||
|
str[i] -= 0x20;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void check_name_and_ext(char *name, char *ext) {
|
|||
|
check_name_or_ext(name, 8);
|
|||
|
check_name_or_ext(ext, 3);
|
|||
|
}
|
|||
|
|
|||
|
void analyse_fullname(char *fullname, char *name, char *ext) {
|
|||
|
int ext_dot_index = -1;
|
|||
|
for (int i = 11; i >= 0; i--) {
|
|||
|
if (fullname[i] == '.') {
|
|||
|
ext_dot_index = i;
|
|||
|
}
|
|||
|
}
|
|||
|
if (ext_dot_index == -1) // 没有后缀名的情况
|
|||
|
{
|
|||
|
memcpy(name, fullname, 8);
|
|||
|
memset(ext, ' ', 3);
|
|||
|
} else if (ext_dot_index == 0) // 没有文件名的情况
|
|||
|
{
|
|||
|
memset(name, ' ', 8);
|
|||
|
memcpy(ext, fullname + 1, 3);
|
|||
|
} else {
|
|||
|
memcpy(name, fullname, ext_dot_index);
|
|||
|
memcpy(ext, fullname + ext_dot_index + 1, 3);
|
|||
|
}
|
|||
|
check_name_and_ext(name, ext);
|
|||
|
}
|
|||
|
|
|||
|
int find_file(char *name, char *ext, struct File *const file) {
|
|||
|
struct File *root_entries = kmalloc(SECTOR_SIZE);
|
|||
|
read_root_dir_sector1(root_entries);
|
|||
|
int isfind = 0;
|
|||
|
for (int i = 0; i < MAX_FILE_NUM; i++) {
|
|||
|
if (memcmp(root_entries[i].name, name, 8) == 0 && memcmp(root_entries[i].ext, ext, 3) == 0) {
|
|||
|
if (file != 0) {
|
|||
|
*file = root_entries[i];
|
|||
|
}
|
|||
|
isfind = 1;
|
|||
|
}
|
|||
|
}
|
|||
|
kfree(root_entries);
|
|||
|
return isfind;
|
|||
|
}
|
|||
|
|
|||
|
struct File *create_dir(char *fullname) {
|
|||
|
char name[8] = {0};
|
|||
|
char ext[3] = {0};
|
|||
|
analyse_fullname(fullname, name, ext);
|
|||
|
int isfind = find_file(name, ext, 0);
|
|||
|
if (isfind) {
|
|||
|
return 0; //文件已存在。
|
|||
|
}
|
|||
|
|
|||
|
struct File *file = (struct File *) kmalloc(32);
|
|||
|
memcpy(file->name, name, 8);
|
|||
|
memcpy(file->ext, " ", 3);
|
|||
|
file->type = 0x10;
|
|||
|
file->time = 0;
|
|||
|
file->date = 0;
|
|||
|
file->clustno = 0;
|
|||
|
file->size = 0;
|
|||
|
|
|||
|
struct File *root_entries = kmalloc(SECTOR_SIZE);
|
|||
|
read_root_dir_sector1(root_entries);
|
|||
|
for (int i = 0; i < MAX_FILE_NUM; i++) {
|
|||
|
if (root_entries[i].name[0] == 0 || root_entries[i].name[0] == 0xe5) { //找一个空闲的文件项存放。
|
|||
|
root_entries[i] = *file;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
save_root_dir_sector1(root_entries);
|
|||
|
kfree(root_entries);
|
|||
|
return file;
|
|||
|
}
|
|||
|
|
|||
|
struct File *create_file(char *fullname) {
|
|||
|
char name[8] = {0};
|
|||
|
char ext[3] = {0};
|
|||
|
analyse_fullname(fullname, name, ext);
|
|||
|
int isfind = find_file(name, ext, 0);
|
|||
|
if (isfind) {
|
|||
|
return 0; //文件已存在。
|
|||
|
}
|
|||
|
|
|||
|
struct File *file = (struct File *) kmalloc(32);
|
|||
|
memcpy(file->name, name, 8);
|
|||
|
memcpy(file->ext, ext, 3);
|
|||
|
file->type = 0x20;
|
|||
|
file->time = 0;
|
|||
|
file->date = 0;
|
|||
|
file->clustno = 0;
|
|||
|
file->size = 0;
|
|||
|
|
|||
|
struct File *root_entries = kmalloc(SECTOR_SIZE);
|
|||
|
read_root_dir_sector1(root_entries);
|
|||
|
for (int i = 0; i < MAX_FILE_NUM; i++) {
|
|||
|
if (root_entries[i].name[0] == 0 || root_entries[i].name[0] == 0xe5) { //找一个空闲的文件项存放。
|
|||
|
root_entries[i] = *file;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
save_root_dir_sector1(root_entries);
|
|||
|
|
|||
|
kfree(root_entries);
|
|||
|
//open_file_task(file);
|
|||
|
kfree(name);
|
|||
|
kfree(ext);
|
|||
|
return file;
|
|||
|
}
|
|||
|
|
|||
|
struct File *open_file(char *fullname) {
|
|||
|
char name[8] = {0};
|
|||
|
char ext[3] = {0};
|
|||
|
analyse_fullname(fullname, name, ext);
|
|||
|
struct File *file = (struct File *) kmalloc(32);
|
|||
|
int isfind = find_file(name, ext, file);
|
|||
|
if (!isfind) {
|
|||
|
kfree(file);
|
|||
|
file = 0;
|
|||
|
} else {
|
|||
|
//set_opened_file(file);
|
|||
|
}
|
|||
|
return file;
|
|||
|
}
|
|||
|
|
|||
|
void alter_file_name(struct File *file, char *new_fullname) {
|
|||
|
char new_name[8] = {0};
|
|||
|
char new_ext[3] = {0};
|
|||
|
analyse_fullname(new_fullname, new_name, new_ext);
|
|||
|
struct File *root_entries = kmalloc(SECTOR_SIZE);
|
|||
|
read_root_dir_sector1(root_entries);
|
|||
|
for (int i = 0; i < MAX_FILE_NUM; i++) {
|
|||
|
if (memcmp(root_entries[i].name, file->name, 8) == 0 && memcmp(root_entries[i].ext, file->ext, 3) == 0) {
|
|||
|
memcpy(root_entries[i].name, new_name, 8);
|
|||
|
memcpy(root_entries[i].ext, new_ext, 3);
|
|||
|
}
|
|||
|
}
|
|||
|
save_root_dir_sector1(root_entries);
|
|||
|
kfree(root_entries);
|
|||
|
}
|
|||
|
|
|||
|
void alter_dir_entry(struct File *file) {
|
|||
|
struct File *root_entries = kmalloc(SECTOR_SIZE);
|
|||
|
read_root_dir_sector1(root_entries);
|
|||
|
for (int i = 0; i < MAX_FILE_NUM; i++) {
|
|||
|
if (memcmp(root_entries[i].name, file->name, 8) == 0 && memcmp(root_entries[i].ext, file->ext, 3) == 0) {
|
|||
|
root_entries[i] = *file;
|
|||
|
}
|
|||
|
}
|
|||
|
save_root_dir_sector1(root_entries);
|
|||
|
kfree(root_entries);
|
|||
|
}
|
|||
|
|
|||
|
void save_file(struct File *file, char *content) {
|
|||
|
unsigned int file_size = strlen(content); //内容大小
|
|||
|
if (file_size == 0 && file->size == 0) {
|
|||
|
return;
|
|||
|
}
|
|||
|
file->size = file_size;
|
|||
|
int sector_num = (file_size + 511) / 512; //将要占用的扇区数
|
|||
|
unsigned short *fat1 = kmalloc(FAT1_SECTORS * SECTOR_SIZE);
|
|||
|
get_fat1(fat1);
|
|||
|
unsigned short clustno = file->clustno;
|
|||
|
unsigned short next_clustno;
|
|||
|
if (file->clustno == 0) //第一次写入
|
|||
|
{
|
|||
|
clustno = 2; //可用簇号从2开始
|
|||
|
while (1) {
|
|||
|
if (*(fat1 + clustno) == 0) //空闲簇号
|
|||
|
{
|
|||
|
file->clustno = clustno; //分配起始簇号
|
|||
|
break;
|
|||
|
} else {
|
|||
|
clustno++;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
int i = 0;
|
|||
|
while (1) {
|
|||
|
write_disk(SECTOR_CLUSTER_BALANCE + clustno, 1, (unsigned int) content);
|
|||
|
if (i == sector_num - 1) { //已写完最后一扇区。
|
|||
|
break;
|
|||
|
}
|
|||
|
i++;
|
|||
|
content += 512;
|
|||
|
next_clustno = *(fat1 + clustno);
|
|||
|
if (next_clustno == 0 || next_clustno >= 0xfff8) { //寻找下一个可用簇号
|
|||
|
next_clustno = clustno + 1;
|
|||
|
while (1) {
|
|||
|
if (*(fat1 + next_clustno) == 0) {
|
|||
|
*(fat1 + clustno) = next_clustno;
|
|||
|
break;
|
|||
|
} else {
|
|||
|
next_clustno++;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
clustno = next_clustno;
|
|||
|
}
|
|||
|
next_clustno = *(fat1 + clustno);
|
|||
|
*(fat1 + clustno) = 0xffff; //0xfff8~0xffff表示文件结束,没有下一个簇了。
|
|||
|
//如果本次写入的内容比上次的少,上次用过的簇号本次用不完,以下将剩下的簇号清零处理。
|
|||
|
if (1 < next_clustno && next_clustno < 0xfff0) {
|
|||
|
while (1) {
|
|||
|
clustno = next_clustno;
|
|||
|
next_clustno = *(fat1 + clustno);
|
|||
|
*(fat1 + clustno) = 0;
|
|||
|
if (next_clustno >= 0xfff8) {
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
alter_dir_entry(file);
|
|||
|
save_fat1(fat1);
|
|||
|
kfree(fat1);
|
|||
|
}
|
|||
|
|
|||
|
void delete_file(struct File *file) {
|
|||
|
//1.标记目录项为已删除。
|
|||
|
struct File *root_entries = kmalloc(SECTOR_SIZE);
|
|||
|
read_root_dir_sector1(root_entries);
|
|||
|
for (int i = 0; i < MAX_FILE_NUM; i++) {
|
|||
|
if (memcmp(root_entries[i].name, file->name, 8) == 0 && memcmp(root_entries[i].ext, file->ext, 3) == 0) {
|
|||
|
root_entries[i].name[0] = 0xe5;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
save_root_dir_sector1(root_entries);
|
|||
|
kfree(root_entries);
|
|||
|
if (file->clustno == 0) {
|
|||
|
return;
|
|||
|
}
|
|||
|
unsigned short *fat1 = kmalloc(FAT1_SECTORS * SECTOR_SIZE);
|
|||
|
get_fat1(fat1);
|
|||
|
unsigned short clustno = file->clustno;
|
|||
|
unsigned short next_clustno = 0;
|
|||
|
while (1) {
|
|||
|
next_clustno = *(fat1 + clustno);
|
|||
|
*(fat1 + clustno) = 0;
|
|||
|
if (next_clustno >= 0xfff8) {
|
|||
|
break;
|
|||
|
}
|
|||
|
clustno = next_clustno;
|
|||
|
}
|
|||
|
save_fat1(fat1);
|
|||
|
kfree(fat1);
|
|||
|
}
|