public FatTable(string fileName, BootSector parentBootSector, string description, int fatTableNumber) { Description = description; ParentBootSector = parentBootSector; Logger = ParentBootSector.Logger; StartAddress = ParentBootSector.GetFatTableStartByte(fatTableNumber); var aLogger = Logger;//to avoid var as ref RawValue = Common.Common.ReadBytesFromImageAsHex(fileName, StartAddress, ParentBootSector.FatSizeInBytes(), ref aLogger); Size = RawValue.Length / 2; if (Size != GetExpectedSize()) { var err = $"in {MethodBase.GetCurrentMethod().Name}.. Actual size of read Fat[{Size}] != Expected size [{GetExpectedSize()}]... Operation terminated"; Logger.LogMessage(err, LogMsgType.Fatal); throw new Exception(err); } if (parentBootSector.FatType == FatType.Fat12) { //I already have the value as Hex so read only 3 hex no need to treat it as bytes ParsedEntries = Conversion.Split(RawValue, 6).ToList(); } }
public FilesystemInformation(BootSector BS, FSInfoSector FSInfo) { InitializeComponent(); this.MaximumSize = this.MinimumSize = this.Size; BootSector = BS; FSInfoSector = FSInfo; //General this.volumeIDLabel.Text = BootSector.GetVolumeID(); this.volumeLabel.Text = BootSector.GetVolumeLabel(); //Boot Sector this.labelBPS.Text = BootSector.GetBytesPerSector().ToString(); this.labelSPC.Text = BootSector.GetSectorsPerCluster().ToString(); this.labelSectoresReservados.Text = BootSector.GetReservedSectors().ToString(); this.labelTotalSectores.Text = BootSector.GetTotalSectoresFAT32().ToString(); this.labelFATSize.Text = BootSector.SizeOfFAT().ToString(); //FSInfo Sector this.lastAllocatedCluster.Text = FSInfoSector.GetLastAllocatedCluster().ToString(); this.freeClusters.Text = FSInfoSector.GetFreeClusterCount().ToString(); //File Allocation Table fatSize.Text = BootSector.SizeOfFAT().ToString(); fat1Offset.Text = BootSector.FATOffset().ToString(); fat2Offset.Text = BootSector.FAT2Offset().ToString(); }
/// <summary> /// Gets the offset of the data (file) area /// </summary> /// <param name="bs"></param> /// <returns>long</returns> /// <exception cref="System.IO.IOException"></exception> public static long GetFilesOffset(BootSector bs) { var offset = GetRootDirOffset(bs); offset += bs.GetRootDirEntryCount() * 32; return(offset); }
static void Main(string[] args) { char driveLetter = 'C'; if (args.Length == 1) { driveLetter = args[0][0]; } using (RawDisk disk = new RawDisk(driveLetter)) { MftDiskExtents res = new MftDiskExtents(); byte[] ntfsBoot = disk.ReadSectors(0, 1); BootSector boot = BootSector.ParseData(ntfsBoot, ntfsBoot.Length, 0); Console.WriteLine("MFT is at LCN " + boot.MFTCluster); MftDetails mft = GetMftDetails(disk, boot); Console.WriteLine("MFT is in " + mft.MftExtents.Length + " extents"); res.Extents.AddRange(mft.MftExtents); using (RawDiskStream diskStream = disk.CreateDiskStream()) using (NtfsDiskStream mftStream = new NtfsDiskStream(diskStream, false, mft.MftExtents, (uint)disk.ClusterSize, 0, (long)mft.MftSize)) { uint sectorsPrRecord = (uint)(boot.MFTRecordSizeBytes / disk.SectorSize); ushort bytesPrSector = (ushort)disk.SectorSize; int records = (int)(mftStream.Length / boot.MFTRecordSizeBytes); byte[] tmp = new byte[boot.MFTRecordSizeBytes]; while (true) { int read = mftStream.Read(tmp, 0, tmp.Length); if (read < boot.MFTRecordSizeBytes) { Console.WriteLine("Stopped reading as we got " + read + " bytes instead of " + tmp.Length + " bytes"); break; } FileRecord rec = FileRecord.Parse(tmp, 0, bytesPrSector, sectorsPrRecord); // Keep track of all external extents to the MFT RecordExternalDiskExtents(rec, res); //// Special case for LIST attributes, since they can further reference more extents outside the MFT //ProcessNonResidentListAttributes(disk, rec); } } long clustersTotal = res.Extents.Sum(x => x.Clusters); Console.WriteLine("To copy: {0:N0} extents", res.Extents.Count); Console.WriteLine("{0:N0} clusters, {1:N0} bytes", clustersTotal, clustersTotal * disk.ClusterSize); } Console.ReadLine(); }
private void GetDiskBootSector() { DiskStream.Seek(0, SeekOrigin.Begin); byte[] bTemp = new byte[512]; DiskStream.Read(bTemp, 0, 512); DiskBootSector = new BootSector(bTemp); DiskBootSector.FATOffset(); DiskBootSector.SectorOffsetForCluster(4); }
public FatSharp(FileStream fatfs) { lock (fatfs) { fatfs.Seek(0, SeekOrigin.Begin); byte[] block = new byte[512]; fatfs.Read(block, 0, 512); BPB = BootSector.Create(block, fatfs); //FatStream = fatfs; } }
/// <summary> /// Gets the offset (in bytes) of the root directory with the given index /// </summary> /// <param name="bs"></param> /// <returns>long</returns> /// <exception cref="System.IO.IOException"></exception> public static long GetRootDirOffset(BootSector bs) { long sectSize = bs.GetBytesPerSector(); var sectsPerFat = bs.GetSectorsPerFat(); var fats = bs.GetNrFats(); var offset = GetFatOffset(bs, 0); offset += fats * sectsPerFat * sectSize; return(offset); }
/// <summary> /// Gets the offset (in bytes) of the fat with the given index /// </summary> /// <param name="bs"></param> /// <param name="fatNr">(0..)</param> /// <returns>long</returns> /// <exception cref="System.IO.IOException"></exception> public static long GetFatOffset(BootSector bs, int fatNr) { long sectSize = bs.GetBytesPerSector(); var sectsPerFat = bs.GetSectorsPerFat(); long resSects = bs.GetNrReservedSectors(); var offset = resSects * sectSize; var fatSize = sectsPerFat * sectSize; offset += fatNr * fatSize; return(offset); }
private void BS_Read() { FileInfo fi = new FileInfo(SelectedFile); //Ok here we go. BootSector bs = BootSector.Load(fi.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None)); DirEntBase[] d = bs.Root.LoadDirEnts(); Print("Loaded {0} DirEnts in the root directory!", d.Length); int free = 0; for (int i = 0; i < d.Length; i++) { DoEvents(); if (d[i].IsLFNEnt) { Print("Entry {0} is a long filename entry.", i); } else if (d[i].IsDIREnt) { string Name = d[i].DirEnt.Filename; if ((Name == "." || Name == "..")) { Print("Entry {0} is a reference to itself or parent directory."); continue; } Print("Entry {0} is a normal Directory Entry.", i); DirectoryEntry de = new DirectoryEntry(d, i); Print("{0}: Short Name: {1}", i, de.ShortFilename); Print("{0}: Long Name: {1}", i, de.LongFilename); Print("{0}: Attributes: {1}", i, de.Attributes); Print("{0}: Starts at Cluster: {1} and is {2} byte(s) long.", i, de.StartCluster, de.FileLength); if ((de.Attributes & FATFileAttribute.SubDirectory) == FATFileAttribute.SubDirectory) { DumpDirectory("/" + de.LongFilename, bs, de.StartCluster); } } else if (d[i].IsDeletedFile) { Print("Entry {0} contains a deleted file", i); Print("{0}: {1}", i, d[i].DirEnt.EightDOTThreeName); } else { free++; } } Print("There are {0} free entries out of {1} total entries", free, d.Length); Print("The root directory is {0}% Full.", Math.Floor(((((double)d.Length - (double)free) / (double)d.Length) * 100))); GC.KeepAlive(bs); }
private void InitiateBoot() { // Read first 512 bytes byte[] data = new byte[512]; _diskStream.Seek(0, SeekOrigin.Begin); _diskStream.Read(data, 0, data.Length); // Parse boot _boot = BootSector.ParseData(data, data.Length, 0); // Get filerecord size BytesPrFileRecord = _boot.MFTRecordSizeBytes; _sectorsPrRecord = _boot.MFTRecordSizeBytes / _boot.BytesPrSector; }
private void CreateBoot() { boot = new BootSector(); byte[] bootSector = boot.DataWritter(); BytesOccupied += (uint)bootSector.Length; var memory = new MemoryStream(); memory.Write(bootSector, 0, bootSector.Length); memory.Flush(); memory.Seek(0, SeekOrigin.Begin); memory.CopyTo(diskStream); //diskStream.Position = bootSector.Length; }
private void DumpDirectory(string Path, BootSector BPB, int ClusterNumber) { Cluster pointer = Cluster.Load(BPB, (ushort)ClusterNumber); Print("In directory:", Path); DirEntBase[] d = pointer.DirectoryEntries; int free = 0; for (int i = 0; i < d.Length; i++) { DoEvents(); if (d[i].IsLFNEnt) { Print("Entry {0} is a long filename entry.", i); } else if (d[i].IsDIREnt) { string Name = d[i].DirEnt.Filename; if ((Name == "." || Name == "..")) { Print("Entry {0} is a reference to itself or parent directory."); continue; } Print("Entry {0} is a normal Directory Entry.", i); DirectoryEntry de = new DirectoryEntry(d, i); Print("{0}: Short Name: {1}", i, de.ShortFilename); Print("{0}: Long Name: {1}", i, de.LongFilename); Print("{0}: Attributes: {1}", i, de.Attributes); Print("{0}: Starts at Cluster: {1} and is {2} byte(s) long.", i, de.StartCluster, de.FileLength); if ((de.Attributes & FATFileAttribute.SubDirectory) == FATFileAttribute.SubDirectory) { DumpDirectory(Path + "/" + de.LongFilename, BPB, de.StartCluster); } } else if (d[i].IsDeletedFile) { Print("Entry {0} contains a deleted file", i); Print("{0}: {1}", i, d[i].DirEnt.EightDOTThreeName); } else { free++; } } }
public void obtenerArchivo(BootSector BS, FileStream stream, FileAllocationTable FAT, String path) { List <byte[]> bytes = new List <byte[]>(); MemoryStream ms = new MemoryStream(); byte[] archivo = null; int Cluster = Entry.GetFirstCluster(); while (Cluster != -1) { //Leer archivo byte[] tempByte = new byte[BS.GetBytesPerSector()]; stream.Seek(BS.SectorOffsetForCluster(Cluster), SeekOrigin.Begin); stream.Read(tempByte, 0, BS.GetBytesPerSector()); bytes.Add(tempByte); //Obtener el siguiente cluster Cluster = FAT.nextClusterInChain(Cluster); } if (bytes.Count > 0) { foreach (byte[] b in bytes) { ms.Write(b, 0, b.Length); } ms.Seek(0, SeekOrigin.Begin); archivo = new byte[Entry.FileSize]; ms.Read(archivo, 0, archivo.Length); Console.WriteLine(ms.Length); } if (archivo != null) { File.WriteAllBytes(path + Entry.NombreDeDir, archivo); MessageBox.Show("Archivo(s) extraido(s) exitosamente!", "Extraccion de Archivo(s)", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { MessageBox.Show("Archivo devuelto en cero!", "Error al extraer archivo", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
private static MftDetails GetMftDetails(RawDisk disk, BootSector boot) { byte[] mftFirst = disk.ReadClusters((long)boot.MFTCluster, 1); FileRecord rec = FileRecord.Parse(mftFirst, 0, (ushort)disk.SectorSize, (uint)(boot.MFTRecordSizeBytes / disk.SectorSize)); // Get DATA attrib // TODO: Handle multiple DATA attributes AttributeGeneric dataAttrib = null; foreach (Attribute attribute in rec.Attributes) { if (attribute.Type == AttributeType.DATA && attribute.AttributeName.Length == 0) { // Got it! dataAttrib = attribute as AttributeGeneric; break; } } Debug.Assert(dataAttrib != null); MftDetails res = new MftDetails(); // Get attribute data // Parse out extents if (dataAttrib.NonResidentFlag == ResidentFlag.Resident) { byte[] dataAttribData = dataAttrib.Data; res.MftSize = dataAttrib.ResidentHeader.ContentLength; res.MftExtents = DataFragment.ParseFragments(dataAttribData, dataAttribData.Length, 0, 0, 0); } else { res.MftSize = dataAttrib.NonResidentHeader.ContentSize; res.MftExtents = dataAttrib.NonResidentHeader.Fragments; } Debug.Assert(res.MftExtents != null); return(res); }
private void Initialize() { byte[] data = new byte[512]; DiskStream.Seek(0, SeekOrigin.Begin); DiskStream.Read(data, 0, data.Length); BootSector = BootSector.ParseData(data, 512, 0); BytesPerFileRecord = BootSector.MftRecordSizeBytes; SectorsPerRecord = BytesPerFileRecord / BytesPerSector; MftFile = ParseMftRecordData(ReadMftRecordData((uint)MetadataMftFiles.Mft)); MftStream = OpenFileRecord(MftFile); AttributeData mftFileData = null; foreach (var att in MftFile.Attributes) { if (att is AttributeData attributeData) { mftFileData = attributeData; } } if (mftFileData == null) { throw new Exception("ntfs error: unable to load mft data"); } long clusterBytes = 0; foreach (var frag in mftFileData.DataFragments) { clusterBytes += frag.Clusters * BytesPerCluster; } FileRecordCount = (uint)(clusterBytes / BytesPerFileRecord); FileRecords = new FileRecord[FileRecordCount]; FileRecords[0] = MftFile; Console.WriteLine("[NTFSDRV2] Initialized with " + FileRecordCount + " file records"); }
void ParseChildren(ref FatDirectoryArea parent, BootSector bs) { if (!parent.IsThisEntryaDirectory()) { return; } int dataAreaStartLoc = parent.GetDataLocation(); List <FatDirectoryArea> longNames = new List <FatDirectoryArea>(); while (true) { var directory = Common.Common.GetUnit <FatDirectoryArea>(fileName, ref aLogger, dataAreaStartLoc, "[Child]DirectoryArea-" + parent.Description, bs); dataAreaStartLoc += Common.Common.FatDirectoryAreaSizeBytes; if (directory.IsEmpty) { break; } if (directory.IsThisEntryaLongFileName()) { longNames.Add(directory); } else { if (longNames.Count > 0) { directory.LongFileNames = longNames; longNames = new List <FatDirectoryArea>(); } parent.ChildrenList.Add(directory); } //if (directory.IsThisEntryaDirectory()) //{ // ParseChildren(ref directory, bs); //} } }
private void Formatear() { try { if (DiskStream != null) { //Nulificar archivo DiskStream.Seek(0, SeekOrigin.Begin); DiskStream.SetLength(0); DiskStream.Flush(); DiskStream.SetLength(DiskSize); DiskStream.Flush(); //Escribir el BootSector BootSector BootSector = new BootSector((int)DiskStream.Length, NewsectorPorCluster, NewVolumeLabel); BootSector.WriteBootSector(DiskStream); //Escribir FSInfoSector FSInfoSector FSInfoSector = new FSInfoSector(); FSInfoSector.WriteInformationSector(DiskStream); //Inicializar Tabla FAT - Offset 32 despues de los sectores reservados FileAllocationTable NewFAT = new FileAllocationTable(BootSector); NewFAT.WriteNewFAT(DiskStream); FSInfoSector.UpdateFreeClusters(1, BootSector); FSInfoSector.UpdateLastAllocatedCluster(2); FSInfoSector.WriteInformationSector(DiskStream); MessageBox.Show("La imagen de disco ha sido formateada!", "Formato Completo", MessageBoxButtons.OK, MessageBoxIcon.Information); } } catch (Exception ex) { MessageBox.Show(ex.ToString()); } }
public FAT(BootSector bs, FileStream fstr) { BPB = bs; //Woops. FATStream = fstr; }
private void InitializeNTFS() { // Read $BOOT if (Provider.MftFileOnly) { Boot = new BootSector(); Boot.OEMCode = "NTFS"; Boot.SectorsPrCluster = 2; // Small cluster Boot.BytesPrSector = 512; // Smallest possible sector // Get FileRecord size (read first record's size) byte[] mft_data = new byte[512]; Provider.ReadBytes(mft_data, 0, 0, mft_data.Length); Boot.MFTRecordSizeBytes = FileRecord.ParseAllocatedSize(mft_data, 0); mft_data = null; } else { byte[] drive_data = new byte[512]; Provider.ReadBytes(drive_data, 0, 0, 512); Boot = BootSector.ParseData(drive_data, 512, 0); drive_data = null; Debug.Assert(Boot.OEMCode == "NTFS"); } // Get FileRecord size BytesPrFileRecord = Boot.MFTRecordSizeBytes; _sectorsPrRecord = BytesPrFileRecord / BytesPrSector; Debug.WriteLine($"Updated BytesPrFileRecord, now set to {BytesPrFileRecord}"); // Prep cache MftRawCache = new RawDiskCache(0); // Read $MFT file record byte[] record_data = ReadMFTRecordData((uint)SpecialMFTFiles.MFT); FileMFT = ParseMFTRecord(record_data); record_data = null; Debug.Assert(FileMFT != null); Debug.Assert(FileMFT.Attributes.Count(s => s.Type == AttributeType.DATA) == 1); AttributeData fileMftData = FileMFT.Attributes.OfType <AttributeData>().Single(); Debug.Assert(fileMftData.NonResidentFlag == ResidentFlag.NonResident); Debug.Assert(fileMftData.DataFragments.Length >= 1); MftStream = OpenFileRecord(FileMFT); // Prep cache long maxLength = MftStream.Length; long toAllocateForCache = Math.Min(maxLength, _rawDiskCacheSizeRecords * BytesPrFileRecord); MftRawCache = new RawDiskCache((int)toAllocateForCache); // Get number of FileRecords FileRecordCount = (uint)((fileMftData.DataFragments.Sum(s => (float)s.Clusters)) * (BytesPrCluster * 1f / BytesPrFileRecord)); FileRecords = new WeakReference[FileRecordCount]; FileRecords[0] = new WeakReference(FileMFT); // Read $VOLUME file record FileRecord fileVolume = ReadMFTRecord(SpecialMFTFiles.Volume); // Get version Attribute versionAttrib = fileVolume.Attributes.SingleOrDefault(s => s.Type == AttributeType.VOLUME_INFORMATION); if (versionAttrib != null) { AttributeVolumeInformation attrib = (AttributeVolumeInformation)versionAttrib; NTFSVersion = new Version(attrib.MajorVersion, attrib.MinorVersion); } }
private void Formatear(FileStream stream) { try { byte SectoresPorCluster = 0x00; //Obtener el numero de sectores por cluster switch (tamanoSectoresPorCluster.SelectedIndex) { case 0: //1 sector por cluster = Clusters de 512 bytes SectoresPorCluster = 0x01; break; case 1: //2 sectores por cluster = Clusters de 1 KiB SectoresPorCluster = 0x02; break; case 2: //4 sectores por cluster = Clusters de 2 KiB SectoresPorCluster = 0x04; break; case 3: //8 sectores por cluster = Clusters de 4 KiB SectoresPorCluster = 0x08; break; case 4: //16 sectores por cluster = Clusters de 8 KiB SectoresPorCluster = 0x10; break; case 5: //32 sectores por cluster = Clusters de 16KiB SectoresPorCluster = 0x20; break; default: SectoresPorCluster = 0x01; break; } //Escribir el BootSector BootSector BootSector = new BootSector((int)stream.Length, SectoresPorCluster, txtVolLabel.Text); BootSector.WriteBootSector(stream); //Escribir FSInfoSector FSInfoSector FSInfoSector = new FSInfoSector(); FSInfoSector.WriteInformationSector(stream); //Inicializar Tabla FAT - Offset 32, despues de los sectores reservados FileAllocationTable NewFAT = new FileAllocationTable(BootSector); NewFAT.WriteNewFAT(stream); FSInfoSector.UpdateFreeClusters(1, BootSector); FSInfoSector.UpdateLastAllocatedCluster(2); FSInfoSector.WriteInformationSector(stream); MessageBox.Show("La imagen de disco ha sido creada y formateada!", "Formato Completo", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } }
private void _read() { _bootSector = new BootSector(m_io, this, m_root); }