Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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));
        }
Beispiel #5
0
        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();
 }