public unsafe Node InitDevice(Node deviceNode) { _Device = deviceNode; initFAT(); /** * Create and add mountpoint */ Node node = new Node(); node.ReadDir = readDirImpl; node.FindDir = findDirImpl; node.Truncate = truncateImpl; node.Flags = NodeFlags.DIRECTORY; /** * Root cookie */ Fat16Cookie rootCookie = new Fat16Cookie(); rootCookie.Cluster = 0xFFFFFFFF; rootCookie.FAT16 = this; node.Cookie = rootCookie; return(node); }
/// <summary> /// Create FS node /// </summary> /// <param name="dirEntry">Direntry</param> /// <param name="cluster">Directory cluster</param> /// <param name="num">Direnty number</param> /// <returns></returns> public Node CreateNode(FatDirEntry *dirEntry, uint cluster, uint num) { Node node = new Node(); node.Size = dirEntry->Size; Fat16Cookie cookie = new Fat16Cookie(); cookie.DirEntry = dirEntry; cookie.Cluster = cluster; cookie.Num = num; cookie.FAT16 = this; node.Cookie = cookie; /** * Is it a directory? */ if ((dirEntry->Attribs & ATTRIB_SUBDIR) == ATTRIB_SUBDIR) { node.ReadDir = readDirImpl; node.FindDir = findDirImpl; node.Flags = NodeFlags.DIRECTORY; } else { node.Read = readImpl; node.Write = writeImpl; node.Truncate = truncateImpl; node.Flags = NodeFlags.FILE; } return(node); }
/// <summary> /// Filesystem truncate implementation /// </summary> /// <param name="node"></param> /// <param name="size"></param> /// <returns></returns> private static uint truncateImpl(Node node, uint size) { /** * Get directory entry from cookie "cache" */ Fat16Cookie cookie = (Fat16Cookie)node.Cookie; FatDirEntry *entry = cookie.DirEntry; Fat16 fat = cookie.FAT16; if (entry == null) { return(0); } /** * Empty file not supported */ if (size == 0) { return(0); } /** * Resize file */ return(fat.ResizeFile(entry, cookie.Cluster, cookie.Num, size)); }
/// <summary> /// Filesystem write implementation /// </summary> /// <param name="node"></param> /// <param name="offset"></param> /// <param name="size"></param> /// <param name="buffer"></param> /// <returns></returns> private static uint writeImpl(Node node, uint offset, uint size, byte[] buffer) { /** * Get directory entry from cookie "cache" */ Fat16Cookie cookie = (Fat16Cookie)node.Cookie; Fat16 fat = cookie.FAT16; FatDirEntry *entry = cookie.DirEntry; uint totalSize = size + offset; /** * Do we need to resize the file? */ if (entry->Size < totalSize) { if (fat.ResizeFile(entry, cookie.Cluster, cookie.Num, totalSize) == 0) { return(0); } } /** * Handle file writing */ return(fat.writeFile(entry->ClusterNumberLo, offset, size, buffer)); }
/// <summary> /// Filesystem read implementation /// </summary> /// <param name="node"></param> /// <param name="offset"></param> /// <param name="size"></param> /// <param name="buffer"></param> /// <returns></returns> private static uint readImpl(Node node, uint offset, uint size, byte[] buffer) { /** * Get directory entry from cookie "cache" */ Fat16Cookie cookie = (Fat16Cookie)node.Cookie; Fat16 fat = cookie.FAT16; FatDirEntry *entry = cookie.DirEntry; /* * If the offset is behind the size, stop here */ if (offset > entry->Size) { return(0); } /* * If bytes to read is bigger than the file size, set the size to the file size minus offset */ if (offset + size > entry->Size) { size = entry->Size - offset; } //Util.PrintStackTrace(6); uint read = fat.readFile(entry->ClusterNumberLo, offset, size, buffer); return(read); }
/// <summary> /// Filesystem read directory implementation /// </summary> /// <param name="node"></param> /// <param name="index"></param> /// <returns></returns> private static DirEntry *readDirImpl(Node node, uint index) { int j = 0; /** * Find cluster number if not root directory */ uint cluster = 0xFFFFFFFF; Fat16Cookie cookie = (Fat16Cookie)node.Cookie; Fat16 fat = cookie.FAT16; if (cookie.DirEntry != null) { FatDirEntry *entry = cookie.DirEntry; cluster = entry->ClusterNumberLo; } /** * Read directory entries */ SubDirectory dir = fat.readDirectory(cluster); for (int i = 0; i < dir.Length; i++) { FatDirEntry entry = dir.DirEntries[i]; /** * Correct attributes? */ if (entry.Name[0] == 0 || entry.Name[0] == (char)0xE5 || entry.Attribs == 0xF || (entry.Attribs & 0x08) > 0) { continue; } /** * Do we need to search further? */ if (j >= index) { DirEntry *outDir = (DirEntry *)Heap.Alloc(sizeof(DirEntry)); outDir->Reclen = (ushort)sizeof(DirEntry); GetName(dir, i, outDir->Name); /** * Directory or file? */ if ((dir.DirEntries[i].Attribs & ATTRIB_SUBDIR) == 0) { outDir->Type = (byte)DT_Type.DT_REG; } else { outDir->Type = (byte)DT_Type.DT_DIR; } return(outDir); } j++; } return(null); }
/// <summary> /// Find directory implementation /// </summary> /// <param name="node">FS Node</param> /// <param name="name">Filename</param> /// <returns></returns> private static Node findDirImpl(Node node, string name) { Fat16Cookie cookie = (Fat16Cookie)node.Cookie; Fat16 fat16 = cookie.FAT16; /** * Calculate lengths (and check if no LFN) */ int length = name.Length; if (length > 12) { return(null); } int dot = name.IndexOf('.'); if (dot > 8) { return(null); } /** * Prepare test memory block */ char *testFor = (char *)Heap.Alloc(11); Memory.Memset(testFor, ' ', 11); int min = (dot == -1) ? Math.Min(length, 8) : Math.Min(dot, 8); int i = 0; for (; i < min; i++) { testFor[i] = String.ToUpper(name[i]); } if (dot != -1) { int lengthExt = length - dot - 1; min = Math.Min(3, lengthExt); i++; for (int j = 0; j < min; j++) { testFor[j + 8] = String.ToUpper(name[i + j]); } } /** * Find cluster number */ uint cluster = 0xFFFFFFFF; if (cookie.DirEntry != null) { FatDirEntry *entry = cookie.DirEntry; cluster = entry->ClusterNumberLo; } /** * Find file in cluster (directory) */ Node nd = fat16.FindFileInDirectory(cluster, testFor); Heap.Free(testFor); return(nd); }