diff --git a/src/include/fileSystem.h b/src/include/fileSystem.h index 65bff6f..1063b2a 100644 --- a/src/include/fileSystem.h +++ b/src/include/fileSystem.h @@ -2,17 +2,20 @@ #define FILE_SYSTEM_H #include +#include enum FileSystemEntryTypes { FS_FOLDER, FS_FILE }; typedef struct { uint8_t type; char *name; + uint32_t cluster; } FileSystemTreeNode; typedef struct { FileSystemTreeNode; uint8_t subType; + uint32_t size; } FileSystemFile; typedef struct { @@ -21,6 +24,15 @@ } FileSystemFolder; typedef struct { + FileSystemFile *file; + char *path, *absolutePath; + Task *task; + void *data; +} File; + +extern File *readFile(char *path); + +typedef struct { uint8_t jmp[3]; char oemName[8]; uint16_t sectorSize; // this is on an odd offset, that's why the packed @@ -50,7 +62,7 @@ FatBootSector *bootSector; uint8_t version; uint32_t fatSize, totalSectorCount, rootDirectorySize, firstDataSector, - firstFatSector, firstRootSector; + firstFatSector, firstRootSector, clusterSize; char *volumeID; HardDrive *hardDrive; void *fat; diff --git a/src/include/fileSystem.h b/src/include/fileSystem.h index 65bff6f..1063b2a 100644 --- a/src/include/fileSystem.h +++ b/src/include/fileSystem.h @@ -2,17 +2,20 @@ #define FILE_SYSTEM_H #include +#include enum FileSystemEntryTypes { FS_FOLDER, FS_FILE }; typedef struct { uint8_t type; char *name; + uint32_t cluster; } FileSystemTreeNode; typedef struct { FileSystemTreeNode; uint8_t subType; + uint32_t size; } FileSystemFile; typedef struct { @@ -21,6 +24,15 @@ } FileSystemFolder; typedef struct { + FileSystemFile *file; + char *path, *absolutePath; + Task *task; + void *data; +} File; + +extern File *readFile(char *path); + +typedef struct { uint8_t jmp[3]; char oemName[8]; uint16_t sectorSize; // this is on an odd offset, that's why the packed @@ -50,7 +62,7 @@ FatBootSector *bootSector; uint8_t version; uint32_t fatSize, totalSectorCount, rootDirectorySize, firstDataSector, - firstFatSector, firstRootSector; + firstFatSector, firstRootSector, clusterSize; char *volumeID; HardDrive *hardDrive; void *fat; diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 6edb5e1..444e498 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -23,8 +23,10 @@ yields(); printCPUData(); setupDevices(); - printf("file system tree:\n"); printFileSystemTree(); + File *file = readFile("/folder/content"); + printf("file size: %i\n", file->file->size); + printf("file content: %s\n", file->data); while (1) { for (Message *message = popBeginning(&(getCurrentTask()->messages)); message; message = popBeginning(&getCurrentTask()->messages)) { diff --git a/src/include/fileSystem.h b/src/include/fileSystem.h index 65bff6f..1063b2a 100644 --- a/src/include/fileSystem.h +++ b/src/include/fileSystem.h @@ -2,17 +2,20 @@ #define FILE_SYSTEM_H #include +#include enum FileSystemEntryTypes { FS_FOLDER, FS_FILE }; typedef struct { uint8_t type; char *name; + uint32_t cluster; } FileSystemTreeNode; typedef struct { FileSystemTreeNode; uint8_t subType; + uint32_t size; } FileSystemFile; typedef struct { @@ -21,6 +24,15 @@ } FileSystemFolder; typedef struct { + FileSystemFile *file; + char *path, *absolutePath; + Task *task; + void *data; +} File; + +extern File *readFile(char *path); + +typedef struct { uint8_t jmp[3]; char oemName[8]; uint16_t sectorSize; // this is on an odd offset, that's why the packed @@ -50,7 +62,7 @@ FatBootSector *bootSector; uint8_t version; uint32_t fatSize, totalSectorCount, rootDirectorySize, firstDataSector, - firstFatSector, firstRootSector; + firstFatSector, firstRootSector, clusterSize; char *volumeID; HardDrive *hardDrive; void *fat; diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 6edb5e1..444e498 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -23,8 +23,10 @@ yields(); printCPUData(); setupDevices(); - printf("file system tree:\n"); printFileSystemTree(); + File *file = readFile("/folder/content"); + printf("file size: %i\n", file->file->size); + printf("file content: %s\n", file->data); while (1) { for (Message *message = popBeginning(&(getCurrentTask()->messages)); message; message = popBeginning(&getCurrentTask()->messages)) { diff --git a/src/kernel/memory/fileSystem.c b/src/kernel/memory/fileSystem.c index 88589ef..3c6c0f3 100644 --- a/src/kernel/memory/fileSystem.c +++ b/src/kernel/memory/fileSystem.c @@ -53,10 +53,10 @@ info->hardDrive = hardDrive; hardDrive->access(hardDrive, info->firstFatSector, info->fat, info->fatSize, 0); - printf("size: %i\n", info->fatSize * info->bootSector->sectorSize * - sizeof(void *) / info->version / 8); info->knownFolders = malloc(info->fatSize * info->bootSector->sectorSize / sizeof(void *) * info->version / 8); + info->clusterSize = + info->bootSector->sectorSize * info->bootSector->sectorsPerCluster; } uint32_t getNextCluster(FatInfo *info, uint32_t cluster) { @@ -70,7 +70,7 @@ bool isClusterEnd(FatInfo *info, uint32_t cluster) { switch (info->version) { case 16: - return cluster == 0xFFFF; + return cluster > 0xFF00; } return true; } @@ -119,8 +119,31 @@ ((cluster - 2) * info->bootSector->sectorsPerCluster); } -void folderScanCluster(FatInfo *info, uint32_t cluster, - FileSystemFolder *parent); +void scanFolder(FatInfo *info, void *data, FileSystemFolder *parent); + +uint16_t getClusterChainLength(FatInfo *info, uint32_t firstCluster) { + uint16_t i = 0; + uint32_t currentCluster = firstCluster; + while (!isClusterEnd(info, currentCluster)) { + currentCluster = getNextCluster(info, currentCluster); + i++; + } + return i; +} + +void *readClusterChain(FatInfo *info, uint32_t firstCluster) { + uint16_t length = getClusterChainLength(info, firstCluster); + void *data = malloc(length * info->clusterSize + 1); + ((uint8_t *)data)[length * info->clusterSize] = 0; + uint32_t currentCluster = firstCluster; + for (uint16_t i = 0; i < length; i++) { + info->hardDrive->access(info->hardDrive, + getClusterSector(info, currentCluster), + data + i * info->clusterSize, + info->bootSector->sectorsPerCluster, 0); + } + return data; +} void setupFolder(char *name, FatDirectoryEntry *directory, FatInfo *info, FileSystemFolder *parent) { @@ -129,6 +152,7 @@ folder->type = FS_FOLDER; uint32_t cluster = directory->firstDataClusterLower | directory->fistDataClusterUpper << 16; + folder->cluster = cluster; listAdd(parent->children, folder); if (info->knownFolders[cluster]) { folder->children = info->knownFolders[cluster]; @@ -141,21 +165,21 @@ folder->children = malloc(sizeof(ListElement **)); info->knownFolders[cluster] = folder->children; *folder->children = NULL; - folderScanCluster(info, getClusterSector(info, cluster), folder); - while (!isClusterEnd(info, cluster)) { - cluster = getNextCluster(info, cluster); - if (cluster > 0xFF00) { - return; - } - folderScanCluster(info, getClusterSector(info, cluster), folder); - } + void *data = readClusterChain(info, cluster); + scanFolder(info, data, folder); + free(data); } -void setupFile(char *name, FileSystemFolder *parent) { +void setupFile(char *name, FatDirectoryEntry *directory, + FileSystemFolder *parent) { FileSystemFile *file = malloc(sizeof(FileSystemFile)); + uint32_t cluster = directory->firstDataClusterLower | + directory->fistDataClusterUpper << 16; + file->cluster = cluster; file->name = name; file->type = FS_FILE; file->subType = 0; + file->size = directory->size; listAdd(parent->children, file); } @@ -168,17 +192,12 @@ if (directoryEntry->attributes & FAT_ATTRIBUTE_DIRECTORY) { setupFolder(name, directoryEntry, info, parent); } else { - setupFile(name, parent); + setupFile(name, directoryEntry, parent); } } -void folderScanCluster(FatInfo *info, uint32_t sector, - FileSystemFolder *parent) { - void *clusterData = malloc(info->bootSector->sectorSize * - info->bootSector->sectorsPerCluster); - info->hardDrive->access(info->hardDrive, sector, clusterData, - info->bootSector->sectorsPerCluster, 0); - FatDirectoryEntry *directory = clusterData; +void scanFolder(FatInfo *info, void *data, FileSystemFolder *parent) { + FatDirectoryEntry *directory = data; ListElement *longName = NULL; uint32_t i; for (i = 0; i < info->bootSector->sectorSize * @@ -200,16 +219,55 @@ parent); } listClear(&longName, true); - free(clusterData); } +FatInfo *info; + void mountDisk(HardDrive *drive) { void *bootSector = malloc(512); drive->access(drive, 0, bootSector, 1, 0); FatBootSector *boot = bootSector; - FatInfo *info = malloc(sizeof(FatInfo)); + info = malloc(sizeof(FatInfo)); setupFatInfo(info, boot, drive); - printf("type: FAT%i\n", info->version); rootFolder.children = malloc(sizeof(ListElement *)); - folderScanCluster(info, info->firstRootSector, &rootFolder); + void *data = malloc(info->clusterSize * info->rootDirectorySize); + info->hardDrive->access(info->hardDrive, info->firstRootSector, data, + info->rootDirectorySize, 0); + scanFolder(info, data, &rootFolder); + free(data); +} + +File *readFile(char *path) { + if (path[0] != '/') { + printf("relative file paths not implemented yet!\n"); + return NULL; + } + char *currentName = path + 1; + FileSystemFolder *currentFolder = &rootFolder; + while (strlen(currentName)) { + foreach (*currentFolder->children) { + FileSystemTreeNode *node = current->data; + uint16_t i; + for (i = 0; currentName[i] != '/' && currentName[i] != 0; i++) { + if (node->name[i] != currentName[i]) { + i = 0; + break; + } + } + if (i != strlen(node->name) || i == 0) { + continue; + } + if (currentName + i == path + strlen(path)) { + File *file = malloc(sizeof(File)); + file->file = (void *)node; + file->absolutePath = path; + file->path = path; + file->data = readClusterChain(info, file->file->cluster); + return file; + } + currentFolder = (void *)node; + currentName += strlen(node->name) + 1; + } + } + return NULL; }