/// <summary> /// Finds the entry. /// </summary> /// <param name="compare">The compare.</param> /// <param name="startCluster">The start cluster.</param> /// <returns></returns> public FatFileLocation FindEntry(FatFileSystem.ICompare compare, uint startCluster) { uint activeSector = startCluster * sectorsPerCluster; if (startCluster == 0) activeSector = (fatType == FatType.FAT32) ? GetSectorByCluster(rootCluster32) : firstRootDirectorySector; uint increment = 0; for (;;) { BinaryFormat directory = new BinaryFormat(partition.ReadBlock(activeSector, 1)); for (uint index = 0; index < entriesPerSector; index++) { if (compare.Compare(directory.Data, index * 32, fatType)) { FatFileAttributes attribute = (FatFileAttributes)directory.GetByte((index * Entry.EntrySize) + Entry.FileAttributes); return new FatFileLocation(GetClusterEntry(directory.Data, index, fatType), activeSector, index, (attribute & FatFileAttributes.SubDirectory) != 0); } if (directory.GetByte(Entry.DOSName + (index * Entry.EntrySize)) == FileNameAttribute.LastEntry) return new FatFileLocation(); } ++increment; if ((startCluster == 0) && (fatType != FatType.FAT32)) { // FAT12/16 Root directory if (increment >= rootDirSectors) return new FatFileLocation(); activeSector = startCluster + increment; continue; } else { // subdirectory if (increment < sectorsPerCluster) { // still within cluster activeSector = startCluster + increment; continue; } // exiting cluster // goto next cluster (if any) uint cluster = GetClusterBySector(startCluster); if (cluster == 0) return new FatFileLocation(); uint nextCluster = GetClusterEntryValue(cluster); if ((IsClusterLast(nextCluster)) || (IsClusterBad(nextCluster)) || (IsClusterFree(nextCluster)) || (IsClusterReserved(nextCluster))) return new FatFileLocation(); activeSector = (uint)(dataAreaStart + (nextCluster - 1 * sectorsPerCluster)); continue; } } }