#include "RamFS.class.h" #include #include "RamFileNode.class.h" RamFS::RamFS() { } RamFS::~RamFS() { delete m_rootNode; } RamFS* RamFS::mount(u32int maxSize, DirectoryNode* mountpoint) { RamFS* rfs = new RamFS(); rfs->m_maxSize = maxSize; rfs->m_usedSize = 0; rfs->m_isWritable = true; rfs->m_rootNode = new DirectoryNode("/", rfs, mountpoint); return rfs; } RamFS* RamFS::mount(u8int *ptr, u32int maxSize, DirectoryNode* mountpoint, bool writable) { RamFS* rfs = new RamFS(); rfs->m_maxSize = maxSize; rfs->m_usedSize = 0; rfs->m_isWritable = true; rfs->m_rootNode = new DirectoryNode("/", rfs, mountpoint); union { u8int* c; initrd_header* i; initrd_file_header* f; } curr; curr.c = ptr; if (curr.i->magic != INITRD_MAGIC) { delete rfs; return NULL; } u32int files = curr.i->files; curr.i++; //Increment pointer of size of initrd header for (u32int i = 0; i < files; i++) { initrd_file_header h = *(curr.f); curr.f++; //Increment pointer of size of file header if (h.name_length != 0 or h.file_length != 0) { String name((const char*)(curr.c)); curr.c += h.name_length + 1; //Increment pointer of length of name //Find out a vector containing parent directories, and set name to the effective file name if (name[0] == WChar("/")) name = name.substr(1, name.size() - 1); //Find node for parent directory String mname = ""; DirectoryNode* parent = rfs->m_rootNode; for (u32int i = 0; i < name.size(); i++) { if (name[i] == WChar("/")) { FSNode* n = parent->getChild(mname); if (n == NULL) break; if (n->type() != NT_DIRECTORY) break; parent = (DirectoryNode*)n; mname.clear(); } else { mname += name[i]; } } name = mname; //Add new node if (h.file_length == 0) { parent->createDirectory(name); } else { FileNode* file = parent->createFile(name); file->write(0, h.file_length, curr.c); curr.c += h.file_length; } } } return rfs; } bool RamFS::unmount() { return m_rootNode->unmountable(); } bool RamFS::setName(FSNode* node, String name) { return true; } bool RamFS::setPermissions(FSNode* node, u32int permissions) { return true; } bool RamFS::setUid(FSNode* node, u32int uid) { return true; } bool RamFS::setGid(FSNode* node, u32int gid) { return true; } bool RamFS::setParent(FSNode* node, FSNode* parent) { if (parent->getFS() == this) return true; return false; } u32int RamFS::read(FileNode* file, u64int position, u32int max_length, u8int *data) { RamFileNode *node = (RamFileNode*) file; if (file->getLength() <= position) return 0; u32int length = file->getLength() - position; if (length > max_length) length = max_length; memcpy(data, node->m_data + position, length); return length; } bool RamFS::write(FileNode* file, u64int position, u32int length, u8int *data) { if (!m_isWritable) return false; RamFileNode *node = (RamFileNode*) file; u32int end = position + length; if (end > node->getLength()) { if (m_usedSize - node->getLength() + end > m_maxSize) return false; m_usedSize -= node->getLength(); m_usedSize += end; u8int* data = (u8int*)Mem::kalloc(end); if (data == 0) return false; //Invalid pointer if (node->m_data != 0) { memcpy(data, node->m_data, node->getLength()); Mem::kfree(node->m_data); } node->m_data = data; node->setLength(end); } memcpy(node->m_data + position, data, length); return true; } bool RamFS::truncate(FileNode* file) { if (!m_isWritable) return false; RamFileNode *node = (RamFileNode*) file; Mem::kfree(node->m_data); node->setLength(0); node->m_data = 0; return true; } bool RamFS::loadContents(DirectoryNode* dir) { return true; } //Nothing to do. FileNode* RamFS::createFile(DirectoryNode* parent, String name) { if (!m_isWritable) return NULL; if (parent->getFS() != this) return NULL; RamFileNode* n = new RamFileNode(name, this, parent); parent->loadContent(); parent->getChildren().push(n); return n; } DirectoryNode* RamFS::createDirectory(DirectoryNode* parent, String name) { if (!m_isWritable) return NULL; if (parent->getFS() != this) return NULL; DirectoryNode* d = new DirectoryNode(name, this, parent); parent->loadContent(); parent->getChildren().push(d); return d; } bool RamFS::remove(DirectoryNode* parent, FSNode* node) { if (node->type() == NT_FILE) { u8int *d = ((RamFileNode*)node)->m_data; if (d != 0) Mem::kfree(d); } return true; }