private static FatEntry ParseFatEntry(byte[] buffer, int offset) { var entry = new FatEntry { ShortName = Encoding.ASCII.GetString(buffer, offset + 0, 8), Ext = Encoding.ASCII.GetString(buffer, offset + 8, 3), Attribute = Num.ArrayToInt(buffer, offset + 11, 1), NTReserved = Num.ArrayToInt(buffer, offset + 12, 1), CreateTimeTenth = Num.ArrayToInt(buffer, offset + 13, 1), CreateTime = Num.ArrayToInt(buffer, offset + 14, 2), CreateDate = Num.ArrayToInt(buffer, offset + 16, 2), LastAccessDate = Num.ArrayToInt(buffer, offset + 18, 2), StartClusterHI = Num.ArrayToInt(buffer, offset + 20, 2), WritetTime = Num.ArrayToInt(buffer, offset + 22, 2), WriteDate = Num.ArrayToInt(buffer, offset + 24, 2), StartClusterLO = Num.ArrayToInt(buffer, offset + 26, 2), FileSize = Num.ArrayToInt(buffer, offset + 28, 4), }; entry.EntryType = buffer[offset + 0]; entry.StartCluster = (entry.StartClusterHI << 16) + entry.StartClusterLO; //copy raw data bytes entry.RawBytes = new byte[FatEntry.Length]; Array.Copy(buffer, offset, entry.RawBytes, 0, entry.RawBytes.Length); return(entry); }
public string CopyFatFileToLocal(FatEntry srcfile, string destdir) { if (srcfile.StartCluster < ValidClusterNumberStart) { AppendEventLog("FileCopy => " + srcfile.FullName + " - Invalid Start Cluster!"); MessageBox.Show("Invalid Start Cluster!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(string.Empty); } if (srcfile.FileSize <= 0) { AppendEventLog("FileCopy => " + srcfile.FullName + " - Invalid file size or empty!"); MessageBox.Show("Invalid file size or empty!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(string.Empty); } var dest = Path.Combine(destdir, srcfile.FullName); AppendEventLog(string.Format("\r\nCopying File: {0}\\{1}, Dest: {2}", _dirpathstr, srcfile.FullName, destdir)); using (var destfile = File.Create(dest)) { _fileManager.Partitions[_selpartition].ReadFile(srcfile, destfile); } return(dest); }
public override IEnumerable <FatEntry> GetDirEntries(long startcluster = ROOT_DIR_FAT_12_16) { var bs = BootSector; var ntfsbs = bs.NtfsBS.First(); var clusternum = startcluster; UpdateProgress(0); EventLog(string.Format("\r\nGetting Directory Entries => Partition: {0}, StartCluster: 0x{1:X8}, $MFT ClusterNum: 0x{2:X8}, $MFTMIRR ClusterNum: 0x{3:X8}", bs.PartitionId, clusternum, ntfsbs.MftFileClusterNum, ntfsbs.MftMirrFileClusterNum)); SystemFiles.FirstOrDefault(p => p.File == NtfsSysFiles.Mft).ClusterNum = ntfsbs.MftFileClusterNum; SystemFiles.FirstOrDefault(p => p.File == NtfsSysFiles.MftMirr).ClusterNum = ntfsbs.MftMirrFileClusterNum; var bytes2read = MFT_FILE_COUNT * MFT_FILE_SIZE; var location = (bs.MbrPartitionTable.First().StartSector + ((long)ntfsbs.MftFileClusterNum * bs.SectorPerCluster)) * bs.BytesPerSector; var buffer = new byte[bytes2read]; EventLog(string.Format("ReadSystemFile => ClusterNum: 0x{0:X8}, Location: 0x{1:X8}, Size: 0x{2:X8}", ntfsbs.MftFileClusterNum, location, bytes2read)); _storageIO.Seek(location); _storageIO.ReadBytes(buffer, buffer.Length); for (int i = 0; i < MFT_FILE_COUNT; i++) { SystemFiles[i].MftEntry = ParseMftEntry(buffer, i * MFT_FILE_SIZE); } var fatentry = new List <FatEntry>(); foreach (var sysfile in SystemFiles) { var entry = new FatEntry { LongName = sysfile.FileName, LfnAvailable = true, Attribute = (int)EntryAttributes.SystemFile, StartCluster = (int)sysfile.ClusterNum, FileSize = (int)sysfile.Size, EntryIndex = sysfile.Index, }; fatentry.Add(entry); } return(fatentry); }
public override void ReadFile(FatEntry file, Stream dest) { var bs = BootSector; var clusternum = file.StartCluster; var bytes2read = file.FileSize; UpdateProgress(0); var location = (bs.MbrPartitionTable.First().StartSector + (clusternum * bs.SectorPerCluster)) * (long)bs.BytesPerSector; EventLog(string.Format("ReadFile => ClusterNum: 0x{0:X8}, Location: 0x{1:X8}, Size: 0x{2:X8}", clusternum, location, bytes2read)); var buffer = new byte[bytes2read]; _storageIO.Seek(location); _storageIO.ReadBytes(buffer, buffer.Length); dest.Write(buffer, 0, buffer.Length); dest.Close(); //var mft = ParseMftEntry(buffer); UpdateProgress(100); EventLog(string.Format("ReadFile Completed: {0} bytes", file.FileSize - bytes2read)); }
public override void ReadFile(FatEntry file, Stream dest) { var bs = file.Partition.BootSector; var clusternum = file.StartCluster; var bytes2read = file.FileSize; long fatlength = bs.FatSizeInBytes; var datacluster = bs.DataClusterLocation; UpdateProgress(0); EventLog(string.Format("ReadFile => ClusterNum: 0x{0:X8}, Location: 0x{1:X8}, Size: 0x{2:X8}, FATlocation: 0x{3:X8}, FATlength: {4} bytes", clusternum, datacluster + GetClusterOffset(clusternum, bs.ClusterSizeInBytes), bytes2read, bs.FatLocation, fatlength)); var fatbytes = new byte[fatlength]; _storageIO.Seek(bs.FatLocation); _storageIO.ReadBytes(fatbytes, fatbytes.Length); UpdateProgress(10); while (bytes2read > 0) { if (clusternum < ClusterNum.PreserveCount) { EventLog("Error: Invalid cluster mark specified in chain!"); break; } else if (clusternum == bs.BadClusterFlagConst) { EventLog("Error: Bad cluster mark found!"); } else if (clusternum >= bs.EofClusterFlagConst) { EventLog("Error: Unexpected end of cluster chain!"); break; } //read file data var databuff = new byte[bs.ClusterSizeInBytes]; _storageIO.Seek(datacluster + GetClusterOffset(clusternum, bs.ClusterSizeInBytes)); _storageIO.ReadBytes(databuff, databuff.Length); //write file data var block2write = bs.ClusterSizeInBytes; if (bytes2read < bs.ClusterSizeInBytes) { block2write = bytes2read; } dest.Write(databuff, 0, block2write); //update progress bytes2read -= block2write; var progress = (long)(file.FileSize - bytes2read) * 100 / file.FileSize; UpdateProgress((int)progress); //get next cluster number if (bs.FsType == FsType.FAT12) { clusternum = GetFAT12NextCluster(fatbytes, clusternum); //FAT12 } else { clusternum = Num.ArrayToInt(fatbytes, clusternum * bs.BytesPerFatConst, bs.BytesPerFatConst); //FAT16 and FAT32 } EventLog(string.Format("ReadFile => NextCluster : 0x{0:X8}, Remaining: {1} bytes", clusternum, bytes2read)); } UpdateProgress(100); EventLog(string.Format("ReadFile Completed: {0} bytes", file.FileSize - bytes2read)); }
public override IEnumerable <FatEntry> GetDirEntries(long startcluster = ROOT_DIR_FAT_12_16) { var bs = BootSector; var clusternum = startcluster; UpdateProgress(0); EventLog(string.Format("\r\nGetting Directory Entries => Partition: {0}, StartCluster: 0x{1:X8}, FATlocation: 0x{2:X8}, FATlength: {3} bytes", bs.PartitionId, clusternum, bs.FatLocation, bs.FatSizeInBytes)); var fatbytes = new byte[bs.FatSizeInBytes]; _storageIO.Seek(bs.FatLocation); _storageIO.ReadBytes(fatbytes, fatbytes.Length); UpdateProgress(40); var progress = 0; var entryCount = 0; var fatentry = new List <FatEntry>(); while (clusternum < bs.EofClusterFlagConst) { long entrylocation; if (clusternum == ROOT_DIR_FAT_12_16) { entrylocation = bs.RootDirLocation; } else { entrylocation = bs.DataClusterLocation + GetClusterOffset(clusternum, bs.ClusterSizeInBytes); } var entrydata = new byte[bs.ClusterSizeInBytes]; _storageIO.Seek(entrylocation); _storageIO.ReadBytes(entrydata, entrydata.Length); EventLog(string.Format("Parsing Directory Entries => ClusterNum: 0x{0:X8}, Location: 0x{1:X8}", clusternum, entrylocation)); UpdateProgress(40 + (progress += 10) % 60); for (int offset = 0; offset < bs.ClusterSizeInBytes; offset += FatEntry.Length) { entryCount++; var entryType = (FatEntryType)entrydata[offset]; EventLog(string.Format("{0:000} => EntryType: 0x{1:X2} -> {2}", entryCount, (byte)entryType, entryType)); if (entryType == FatEntryType.Null) { break; } if (entryType == FatEntryType.ExFatVolumeLabel) { var exentry = ParseExFatVolumeLableEntry(entrydata, offset); var entry = new FatEntry { Attribute = (int)EntryAttributes.VolumeLabel, LongName = exentry.VolumeLabel, LfnAvailable = true, EntryIndex = entryCount, Partition = this }; fatentry.Add(entry); } else if (entryType == FatEntryType.AllocationBMP) { var exentry = ParseExFatAllocationBmpEntry(entrydata, offset); var entry = new FatEntry { LongName = ((FatEntryType)exentry.EntryType).ToString(), StartCluster = (int)exentry.FirstCluster, FileSize = (int)exentry.DataLength, LfnAvailable = true, EntryIndex = entryCount, Partition = this }; fatentry.Add(entry); } else if (entryType == FatEntryType.UpCaseTable) { var exentry = ParseExFatUpCaseTableEntry(entrydata, offset); var entry = new FatEntry { LongName = ((FatEntryType)exentry.EntryType).ToString(), StartCluster = (int)exentry.FirstCluster, FileSize = (int)exentry.DataLength, LfnAvailable = true, EntryIndex = entryCount, Partition = this }; fatentry.Add(entry); } else if (entryType == FatEntryType.ExFatFileDirectory) { lastFileEntry = new FatEntry(); lastFileEntry.LongName = ""; lastFileEntry.LfnAvailable = true; lastFileEntry.EntryIndex = entryCount; lastFileEntry.Partition = this; var exentry = ParseExFatFileEntry(entrydata, offset); lastFileEntry.Attribute = exentry.Attribute; lastFileEntry.EntrySetCount = exentry.SecondaryCount; } else if (entryType == FatEntryType.StreamExt) { var streamExt = ParseExFatStreamExtEntry(entrydata, offset); lastFileEntry.StartCluster = (int)streamExt.FirstCluster; lastFileEntry.FileSize = (int)streamExt.DataLength; } else if (entryType == FatEntryType.ExFatFileName) { var lfnentry = ParseExFatFileNameEntry(entrydata, offset); lastFileEntry.LongName += lfnentry.FileName; } if (lastFileEntry != null) { entrySetCount++; if (entrySetCount >= lastFileEntry.EntrySetCount + 1) { fatentry.Add(lastFileEntry); entrySetCount = 0; lastFileEntry = null; } } } //get next cluster number if (bs.FsType == FsType.FAT12) { clusternum = GetFAT12NextCluster(fatbytes, (int)clusternum); } else { clusternum = Num.ArrayToLong(fatbytes, clusternum * bs.BytesPerFatConst, bs.BytesPerFatConst); } EventLog(string.Format("Parsing Directory Entries => NextCluster: 0x{0:X8}", clusternum)); if (clusternum < ClusterNum.PreserveCount) { EventLog("Invalid cluster number specified in chain"); break; } else if (clusternum == bs.BadClusterFlagConst) { EventLog("Bad cluster mark found"); } } UpdateProgress(100); EventLog("Valid FAT Entry Found: " + fatentry.Count); return(fatentry); }
public virtual void DeleteFile(FatEntry file) { throw new NotImplementedException(); }
public virtual FatEntry CreateFile(FatEntry directory) { throw new NotImplementedException(); }
public virtual void WriteFile(FatEntry file, Stream source) { throw new NotImplementedException(); }
public virtual void ReadFile(FatEntry file, Stream dest) { throw new NotImplementedException(); }