Exemplo n.º 1
0
        public void printData(FileRecordSegmentHeader folder, string name)
        {
            foreach (var node in ((IndexRoot)folder.attributes.ElementAt(2)).Children)
            {
                if (((FileName)node.attributes.ElementAt(1)).Filename.Equals(name))
                {
                    Console.WriteLine();
                    Console.WriteLine("About the MFT entry (STANDARD_INFORMATION + FILE_NAME + DATA):");
                    Console.WriteLine("Entry was created : {0}", ((StandardInformation)node.attributes.ElementAt(0)).CreationTime);
                    Console.WriteLine("Entry was last modified : {0}", ((StandardInformation)node.attributes.ElementAt(0)).ModifiedTime);
                    Console.WriteLine("Entry was last accessed : {0}", ((StandardInformation)node.attributes.ElementAt(0)).AccessTime);
                    Console.WriteLine("MFT for Entry was last changed : {0}", ((StandardInformation)node.attributes.ElementAt(0)).MFTChangeTime);
                    Console.WriteLine();

                    Console.WriteLine("About the DATA:");
                    Console.WriteLine("File was created : {0}", ((FileName)node.attributes.ElementAt(1)).CreationTime);
                    Console.WriteLine("File was last modified : {0}", ((FileName)node.attributes.ElementAt(1)).ModifiedTime);
                    Console.WriteLine("File was last accessed : {0}", ((FileName)node.attributes.ElementAt(1)).AccessTime);
                    Console.WriteLine("MFT for file was last changed : {0}", ((FileName)node.attributes.ElementAt(1)).MFTChangeTime);
                    Console.WriteLine("Real size : {0}", ((FileName)node.attributes.ElementAt(1)).RealSize);
                    Console.WriteLine("Allocated size : {0}", ((FileName)node.attributes.ElementAt(1)).AllocatedSize);
                    Console.WriteLine();

                    Console.WriteLine("Starting from the MFT header for this file (starting address is a local 0):");
                    Console.WriteLine("STANDARD_INFORMATION offset: 24B");
                    Console.WriteLine("FILE_NAME offset: {0}B", 24 + ((StandardInformation)node.attributes.ElementAt(0)).RecordLength);
                    Console.WriteLine("DATA offset: {0}B", 24 + ((StandardInformation)node.attributes.ElementAt(0)).RecordLength + ((FileName)node.attributes.ElementAt(1)).RecordLength);
                    Console.WriteLine();

                    break;
                }
            }
        }
Exemplo n.º 2
0
 public void CreateFileRecordHeader(MFTEntryFlags flag, FileRecordSegmentHeader parent)
 {
     MSH = new MultiSectorHeader();
     FirstAttributeOffset = 42;
     Flags = flag;
     if (Flags == MFTEntryFlags.FileRecordSegmentInUse)
     {
         TotalEntrySize = 64_000;
         UsedFolderSize = AllocatedFolderSize = 0;
     }
     else
     {
         UsedEntrySize = TotalEntrySize = 0;
         // UsedEntrySize for folders is size of the Stndfile + FileName file + IndexRoot file
         if (parent == null) // root folder
         {
             this.parent = null;
         }
         else
         {
             this.parent = parent;
         }
     }
     UsedEntrySize = 42;
 }
Exemplo n.º 3
0
        private void CreateRoot(string name)
        {
            Root = new FileRecordSegmentHeader();
            Root.CreateFileRecordHeader(Enums.MFTEntryFlags.FileNameIndexPresent, null);

            StandardInformation stdInfo = new StandardInformation();

            stdInfo.CreateStandInfoFile(FileAttributes.Normal);
            Root.UsedEntrySize += stdInfo.RecordLength;

            IndexRoot indRoot = new IndexRoot();
            //Root.UsedEntrySize += (uint)indRoot.numberOfChildren * 8; // reference is 8 B

            FileName fileName = new FileName();

            fileName.CreateFileNameFile(name);
            fileName.RealSize   = fileName.AllocatedSize = 0;
            Root.UsedEntrySize += fileName.RecordLength;

            Root.attributes.Add(stdInfo);
            Root.attributes.Add(fileName);
            Root.attributes.Add(indRoot);

            BytesOccupied += Root.UsedEntrySize;
        }
Exemplo n.º 4
0
        public void changeName(FileRecordSegmentHeader folder, string oldName, string newName)
        {
            foreach (var node in ((IndexRoot)folder.attributes.ElementAt(2)).Children)
            {
                if (((FileName)node.attributes.ElementAt(1)).Filename.Equals(oldName))
                {
                    if ((newName.Length > oldName.Length && (node.TotalEntrySize - node.UsedEntrySize) > newName.Length) || newName.Length <= oldName.Length)
                    {
                        node.UsedEntrySize += (uint)(newName.Length - oldName.Length);

                        string theName;
                        if (node.attributes.ElementAt(2) is Data)
                        {
                            string[] split = ((FileName)node.attributes.ElementAt(1)).Filename.Split('.');
                            split[0] = newName;
                            theName  = split[0] + "." + split[1];
                        }
                        else
                        {
                            theName = newName;
                        }

                        FileName fn = new FileName();
                        fn.CreateFileNameFile(theName);
                        fn.CreationTime    = ((FileName)node.attributes.ElementAt(1)).CreationTime;
                        fn.AllocatedSize   = ((FileName)node.attributes.ElementAt(1)).AllocatedSize;
                        fn.RealSize        = ((FileName)node.attributes.ElementAt(1)).RealSize;
                        node.attributes[1] = fn;
                    }
                    break;
                }
            }
        }
Exemplo n.º 5
0
        public FileRecordSegmentHeader FindFolder(FileRecordSegmentHeader folder, string searchDir)
        {
            foreach (var child in ((IndexRoot)folder.attributes.ElementAt(2)).Children)
            {
                if (((FileName)child.attributes.ElementAt(1)).Filename.Equals(searchDir))
                {
                    return(child);
                }
            }

            return(null);
        }
Exemplo n.º 6
0
        public byte[] searchDataInDirectory(FileRecordSegmentHeader dir, string name)
        {
            foreach (var child in ((IndexRoot)dir.attributes.ElementAt(2)).Children)
            {
                if (((FileName)child.attributes.ElementAt(1)).Filename.Equals(name))
                {
                    return(((Data)child.attributes.ElementAt(2)).DataBytes);
                }
            }

            return(null);
        }
Exemplo n.º 7
0
        public IEnumerable <FileRecordSegmentHeader> GetRecord()
        {
            while (true)
            {
                FileRecordSegmentHeader record = ReadNextRecord();

                if (record == null)
                {
                    break;
                }

                yield return(record);
            }
        }
Exemplo n.º 8
0
        static void CreateFile(FileRecordSegmentHeader parentFolder, FileRecordSegmentHeader childFile, string name, NtfsFileSystem fs)
        {
            childFile.CreateFileRecordHeader(Enums.MFTEntryFlags.FileRecordSegmentInUse, parentFolder);

            StandardInformation stdInfo = new StandardInformation();

            stdInfo.CreateStandInfoFile(FileAttributes.Normal);
            childFile.UsedEntrySize += stdInfo.RecordLength;

            FileName fileName = new FileName();

            fileName.CreateFileNameFile(name);
            childFile.UsedEntrySize += fileName.RecordLength;

            fileName.AllocatedSize   = childFile.TotalEntrySize - childFile.UsedEntrySize;
            fileName.RealSize        = 0;
            childFile.UsedEntrySize += (uint)fileName.RealSize;

            Data data = new Data();

            childFile.attributes.Add(stdInfo);
            childFile.attributes.Add(fileName);
            childFile.attributes.Add(data);

            if (childFile.TotalEntrySize < (fs.VolumeSize - fs.BytesOccupied) + 8) // +8 for reference in folder
            {
                fs.mftHeaderRecord.Add(childFile);

                ((FileSystem.Attributes.Indexroot.IndexRoot)parentFolder.attributes.ElementAt(2)).Children.Add(childFile);
                ((FileSystem.Attributes.Indexroot.IndexRoot)parentFolder.attributes.ElementAt(2)).numberOfChildren++;
                childFile.parent = parentFolder;
                fs.FileRecordCount++;
                fs.BytesOccupied            += 8; // one child added
                fs.BytesOccupied            += childFile.TotalEntrySize;
                parentFolder.UsedFolderSize += childFile.TotalEntrySize;
            }
            else
            {
                Console.WriteLine("Volume is full!");
                Save(fs.VolName.Name, fs.Save());
                Environment.Exit(0);
            }
        }
Exemplo n.º 9
0
        public static FileRecordSegmentHeader ReadFileRecord(byte[] data, int offset, ushort bytesPerSector, uint sectors)
        {
            uint length = bytesPerSector * sectors;

            if (data.Length - offset < length || length < 50 || !(bytesPerSector % 512 == 0 && bytesPerSector > 0) || sectors < 0)
            {
                throw new Exception("Error in parsing the 'FILE_RECORD_SEGMENT_HEADER'!\n");
            }

            FileRecordSegmentHeader record = new FileRecordSegmentHeader();

            //                                                                                                          offset      size
            record.MSH                      = new MultiSectorHeader(data, offset);                                      //  0      4+2+2=8
            record.LSN                      = BitConverter.ToUInt64(data, offset + 8);                                  //  8         8
            record.SequenceNumber           = BitConverter.ToUInt16(data, offset + 16);                                 // 16         2
            record.ReferenceLinkCount       = BitConverter.ToInt16(data, offset + 18);                                  // 18         2
            record.FirstAttributeOffset     = BitConverter.ToUInt16(data, offset + 20);                                 // 20         2
            record.Flags                    = (MFTEntryFlags)BitConverter.ToUInt16(data, offset + 22);                  // 22         2
            record.UsedEntrySize            = BitConverter.ToUInt32(data, offset + 24);                                 // 24         4
            record.TotalEntrySize           = BitConverter.ToUInt32(data, offset + 32);                                 // 28         4
            record.BaseFileRecordSegment    = new MFTSegmentReference(BitConverter.ToUInt64(data, offset + 32));        // 32         8
            record.FirstNextFreeAttributeId = BitConverter.ToUInt16(data, offset + 40);                                 // 40         2
            // Used to align to 4-byte boundary (only since NTFS version 3.1) [offset : 0x2A]                           // 42         2
            record.MFTNumber = BitConverter.ToUInt16(data, offset + 44);                                                // 44         4

            record.UpdateSequenceArray = new byte[2];
            Array.Copy(data, offset + record.MSH.UpdateSequenceArrayOffset, record.UpdateSequenceArray, 0, 2);

            record.SequenceArray = new byte[record.MSH.SequenceArraySize * 2 - 2];
            Array.Copy(data, offset + record.MSH.UpdateSequenceArrayOffset + 2, record.SequenceArray, 0, record.SequenceArray.Length);

            record.MftSegmentReference = new MFTSegmentReference(record.MFTNumber, record.SequenceNumber);

            NtfsHelper.ApplyUpdateSequenceNumberPatch(data, offset, sectors, bytesPerSector, record.UpdateSequenceArray, record.SequenceArray);

            record.attributes = new List <AttributeRecord>();
            //record.externalAttributes = new List<AttributeRecord>();

            record.ReadAttributes(data, record.UsedEntrySize - record.FirstAttributeOffset, offset + record.FirstAttributeOffset);

            return(record);
        }
Exemplo n.º 10
0
        //private void ReadBoot()
        //{
        //    byte[] data = new byte[512];
        //    diskStream.Seek(0, SeekOrigin.Begin);
        //    diskStream.Read(data, 0, data.Length);

        //    boot = BootSector.DataReader(data, data.Length, 0);         // parsing boot

        //    BytesPerFileRecord = boot.ExtenedBPB.ClustersPerMFTRecord;
        //    sectorsPerRecord = boot.ExtenedBPB.ClustersPerMFTRecord / boot.BIOSParameterBlock.BytesPerSector;
        //}

        //private void ReadMFT()
        //{
        //    buffer = new byte[BytesPerFileRecord];
        //    diskStream.Seek((long)(boot.ExtenedBPB.MFTClusterNumber * BytesPerCluster), SeekOrigin.Begin);
        //    diskStream.Read(buffer, 0, buffer.Length);

        //    FileRecordSegmentHeader record = FileRecordSegmentHeader.ReadFileRecord(buffer, 0, boot.BIOSParameterBlock.BytesPerSector, sectorsPerRecord);
        //    mftHeaderRecord = record;

        //    // mftStream = new NtfsDiskStream(diskStream, BytesPerCluster);
        //    CurrentMftRecordNumber = 0;
        //    FileRecordCount = (uint)(mftStream.Length / BytesPerFileRecord);
        //}

        public FileRecordSegmentHeader ReadNextRecord()
        {
            uint newPosition = CurrentMftRecordNumber * BytesPerFileRecord;

            if (mftStream.Position != newPosition)
            {
                mftStream.Seek(newPosition, SeekOrigin.Begin);
            }

            if (mftStream.Read(buffer, 0, buffer.Length) == 0)
            {
                return(null);
            }

            FileRecordSegmentHeader record = FileRecordSegmentHeader.ReadFileRecord(buffer, 0, boot.BIOSParameterBlock.BytesPerSector, sectorsPerRecord);

            CurrentMftRecordNumber = record.MFTNumber + 1;

            return(record);
        }
Exemplo n.º 11
0
        //static void MessageWrite(string str)
        //{
        //    Console.Write(">" + "{0} {1}\n>", str, message1);
        //    Console.ReadLine();
        //}

        static void CreateDirectory(FileRecordSegmentHeader parentFolder, FileRecordSegmentHeader childFolder, string name, NtfsFileSystem fs)
        {
            childFolder.CreateFileRecordHeader(Enums.MFTEntryFlags.FileNameIndexPresent, parentFolder);

            StandardInformation stdInfo = new StandardInformation();

            stdInfo.CreateStandInfoFile(FileAttributes.Normal);
            childFolder.UsedEntrySize += stdInfo.RecordLength;

            IndexRoot indRoot = new IndexRoot();
            //childFolder.UsedEntrySize += indRoot.RecordLength;

            FileName fileName = new FileName();

            fileName.CreateFileNameFile(name);
            fileName.RealSize          = fileName.AllocatedSize = 0;
            childFolder.UsedEntrySize += fileName.RecordLength;

            if (childFolder.UsedEntrySize >= (fs.VolumeSize - fs.BytesOccupied + 8))
            {
                Console.WriteLine("Volume is full!");
                Save(fs.VolName.Name, fs.Save());
                Environment.Exit(0);
            }

            childFolder.attributes.Add(stdInfo);
            childFolder.attributes.Add(fileName);
            childFolder.attributes.Add(indRoot);

            ((IndexRoot)parentFolder.attributes.ElementAt(2)).Children.Add(childFolder);
            ((IndexRoot)parentFolder.attributes.ElementAt(2)).numberOfChildren++;
            childFolder.parent = parentFolder;

            fs.BytesOccupied += childFolder.UsedEntrySize + 8;
            fs.DirectoryRecordCount++;
            parentFolder.UsedFolderSize += childFolder.UsedEntrySize;
        }
Exemplo n.º 12
0
        static void Main(string[] args)
        {
            string command, fsName, subDir1, subDir2, currentDir;

            subDir1 = subDir2 = string.Empty;

            while (true)
            {
                Console.Clear();
                Console.Write(">" + "Enter Filesystem name!\n>");
                command = Console.ReadLine();
                //command.Substring(command.IndexOf(">"));
                if (Regex.IsMatch(command, @"^[A-Za-z0-9]+$"))
                {
                    fsName = command;
                    break;
                }
                else
                {
                    Console.Write(">" + "FS name is not valid!" + message1);
                    Console.ReadLine();
                }
            }
            NtfsFileSystem ntfsFS = new NtfsFileSystem(fsName);

            currentDir = fsName;
            var currectFolder = ntfsFS.Root;

            Console.Clear();
            while (true)
            {
                Console.Write("{0}:\\{1}{2}>", fsName, subDir1 == string.Empty ? subDir1 : subDir1 + "\\", subDir2);
                string[] textCatch = Console.ReadLine().Split('"');       // e.q. textCatch[1] is "text for input."
                string[] tokens    = (textCatch[0].ToLower()).Split(' '); //string[] tokens = command.Split(' ');
                command = tokens[0];
                command = command.Trim();
                bool   toContinue = true;
                choice selected   = choice.wrong_command;

                {
                    int i = 0;
                    foreach (var ch in choices)
                    {
                        if (command.Equals(choices[i++].Item1))
                        {
                            selected = (choice)(--i);
                        }

                        if (ch.Item1.Equals(command) && (tokens.Length - 1 >= ch.Item2 && tokens.Length - 1 <= ch.Item3))
                        {
                            toContinue = false;
                            break;
                        }
                    }
                }

                if (toContinue)
                {
                    Console.Write("{0}:\\>{1} {2}\n", fsName, "Command has wrong number of arguments!", message1);
                    //Console.ReadLine();
                    continue;
                }

                //for (int i = 0; i < (int)choice.cd_remove; ++i)
                //    if (command.Equals(choices[i].Item1))
                //    {
                //        selected = (choice)i;
                //        break;
                //    }

                if (selected != choice.wrong_command)
                {
                    switch (selected)
                    {
                    case choice.mkdir:
                    {
                        if (!(subDir1 != String.Empty && subDir2 != String.Empty))
                        {
                            FileRecordSegmentHeader mkFolder = new FileRecordSegmentHeader();
                            CreateDirectory(currectFolder, mkFolder, tokens[1], ntfsFS);
                        }
                        else
                        {
                            Console.WriteLine("Allowed directory depth is 2. Can't make {0} directory!", tokens[1]);
                        }

                        break;
                    }

                    case choice.create:
                    {
                        FileRecordSegmentHeader createFile = new FileRecordSegmentHeader();
                        CreateFile(currectFolder, createFile, tokens[1], ntfsFS);

                        break;
                    }

                    case choice.put:
                    {
                        //if (Directory.Exists(tokens[1]))
                        using (var stream = new FileStream(tokens[1], FileMode.Open))
                        {
                            if (stream.Length <= 64_000)
                            {
                                try
                                {
                                    FileRecordSegmentHeader header = new FileRecordSegmentHeader();
                                    FileRecordSegmentHeader parent = currectFolder;

                                    header.CreateFileRecordHeader(Enums.MFTEntryFlags.FileRecordSegmentInUse, parent);

                                    StandardInformation stdInfo = new StandardInformation();
                                    stdInfo.CreateStandInfoFile(FileAttributes.Normal);
                                    header.UsedEntrySize += stdInfo.RecordLength;

                                    FileName fileName = new FileName();
                                    fileName.CreateFileNameFile(Path.GetFileName(tokens[1]));
                                    header.UsedEntrySize += fileName.RecordLength;

                                    if (stream.Length <= (header.TotalEntrySize - header.UsedEntrySize))
                                    {
                                        fileName.AllocatedSize = header.TotalEntrySize - header.UsedEntrySize;
                                        fileName.RealSize      = (ulong)stream.Length;
                                        header.UsedEntrySize  += (uint)fileName.RealSize;

                                        Data data = new Data();
                                        var  mem  = new MemoryStream();
                                        stream.CopyTo(mem);
                                        data.DataBytes = mem.ToArray();

                                        header.attributes.Add(stdInfo);
                                        header.attributes.Add(fileName);
                                        header.attributes.Add(data);

                                        if (header.TotalEntrySize < (ntfsFS.VolumeSize - ntfsFS.BytesOccupied) + 8)         // +8 for reference in folder
                                        {
                                            ntfsFS.mftHeaderRecord.Add(header);

                                            ((FileSystem.Attributes.Indexroot.IndexRoot)parent.attributes.ElementAt(2)).Children.Add(header);
                                            ((FileSystem.Attributes.Indexroot.IndexRoot)parent.attributes.ElementAt(2)).numberOfChildren++;
                                            header.parent = parent;

                                            ntfsFS.FileRecordCount++;
                                            ntfsFS.BytesOccupied  += 8;         // one child added
                                            ntfsFS.BytesOccupied  += header.TotalEntrySize;
                                            parent.UsedFolderSize += header.TotalEntrySize;
                                        }
                                        else
                                        {
                                            Save(fsName, ntfsFS.Save());
                                            throw new Exception("Volume is full!");
                                        }
                                    }
                                    else
                                    {
                                        Console.WriteLine("File is too large!");
                                    }
                                }
                                catch (Exception e)
                                {
                                    Console.WriteLine(e);
                                    Environment.Exit(0);
                                }
                            }
                            else
                            {
                                Console.WriteLine("File is larger than 64 KB!");
                            }
                        }
                        //else
                        //    Console.WriteLine("Directory '{0}' doesn't exist!", tokens[1]);

                        break;
                    }

                    case choice.get:
                    {
                        //FileInfo fileInfo = new FileInfo(tokens[1]);
                        //using (FileStream fs = fileInfo.Create())
                        //{
                        byte[] data = ntfsFS.searchDataInDirectory(currectFolder, tokens[2]);
                        if (data != null)
                        {
                            File.WriteAllBytes(tokens[1], data);
                        }
                        else
                        {
                            Console.WriteLine("File is not located in the current folder!");
                        }

                        break;
                    }

                    case choice.ls:
                    {
                        Console.WriteLine();
                        foreach (var child in ((FileSystem.Attributes.Indexroot.IndexRoot)currectFolder.attributes.ElementAt(2)).Children)
                        {
                            if (child.Flags == Enums.MFTEntryFlags.FileRecordSegmentInUse)
                            {
                                Console.WriteLine(((StandardInformation)child.attributes.ElementAt(0)).CreationTime.ToString() + "    " + "    " +
                                                  child.UsedEntrySize.ToString("N1") + " " + ((FileName)child.attributes.ElementAt(1)).Filename);
                            }
                            else
                            {
                                Console.WriteLine(((StandardInformation)child.attributes.ElementAt(0)).CreationTime.ToString() + "    " + "<DIR>" +
                                                  "     " + ((FileName)child.attributes.ElementAt(1)).Filename);
                            }
                        }
                        Console.WriteLine();
                        break;
                    }

                    case choice.cp:
                    {
                        try
                        {
                            // get the file
                            FileRecordSegmentHeader fileToCpy = null;
                            FileRecordSegmentHeader header    = new FileRecordSegmentHeader();
                            FileRecordSegmentHeader parent    = null;

                            foreach (var child in ((FileSystem.Attributes.Indexroot.IndexRoot)currectFolder.attributes.ElementAt(2)).Children)
                            {
                                if (((FileName)child.attributes.ElementAt(1)).Filename.Equals(tokens[1]))
                                {
                                    fileToCpy = child;
                                    break;
                                }
                            }

                            if (fileToCpy != null)
                            {
                                string[] splitDestination = tokens[2].Split('\\');
                                if (splitDestination.Length > 2)
                                {
                                    Console.WriteLine("Moving failed!");
                                }
                                else
                                {
                                    FileRecordSegmentHeader moveFolder = null;
                                    FileRecordSegmentHeader tmp        = null;
                                    foreach (var child in ((FileSystem.Attributes.Indexroot.IndexRoot)currectFolder.parent.attributes.ElementAt(2)).Children)
                                    {
                                        if (((FileName)child.attributes.ElementAt(1)).Filename.Equals(splitDestination[0]))
                                        {
                                            tmp = moveFolder = child;
                                            break;
                                        }
                                    }

                                    if (moveFolder != null)
                                    {
                                        if (splitDestination.Length == 2)
                                        {
                                            foreach (var child in ((FileSystem.Attributes.Indexroot.IndexRoot)tmp.attributes.ElementAt(2)).Children)
                                            {
                                                if (((FileName)child.attributes.ElementAt(1)).Filename.Equals(splitDestination[1]))
                                                {
                                                    moveFolder = child;
                                                    break;
                                                }
                                            }

                                            if ((tmp != moveFolder && splitDestination.Length == 2) || (tmp == moveFolder && splitDestination.Length == 1))
                                            {
                                                //((FileSystem.Attributes.Indexroot.IndexRoot)currectFolder.attributes.ElementAt(2)).Children.Remove(moveFolder);
                                                //((FileSystem.Attributes.Indexroot.IndexRoot)moveFolder.attributes.ElementAt(2)).Children.Add(moveFolder);
                                                //moveFolder.parent = moveFolder;

                                                parent = moveFolder;
                                                header.CreateFileRecordHeader(Enums.MFTEntryFlags.FileRecordSegmentInUse, parent);

                                                StandardInformation stdInfo = new StandardInformation();
                                                stdInfo.CreateStandInfoFile(FileAttributes.Normal);
                                                header.UsedEntrySize += stdInfo.RecordLength;

                                                FileName fileName = new FileName();
                                                fileName.CreateFileNameFile(((FileName)fileToCpy.attributes.ElementAt(1)).Filename);
                                                header.UsedEntrySize += fileName.RecordLength;

                                                fileName.AllocatedSize = header.TotalEntrySize - header.UsedEntrySize;
                                                fileName.RealSize      = (ulong)((FileName)fileToCpy.attributes.ElementAt(1)).RealSize;
                                                header.UsedEntrySize  += (uint)fileName.RealSize;

                                                Data data = new Data();
                                                Array.Copy(((Data)fileToCpy.attributes.ElementAt(2)).DataBytes, 0, data.DataBytes, 0, ((Data)fileToCpy.attributes.ElementAt(2)).DataBytes.Length);


                                                header.attributes.Add(stdInfo);
                                                header.attributes.Add(fileName);
                                                header.attributes.Add(data);

                                                if (header.TotalEntrySize < (ntfsFS.VolumeSize - ntfsFS.BytesOccupied) + 8)         // +8 for reference in folder
                                                {
                                                    ntfsFS.mftHeaderRecord.Add(header);

                                                    ((FileSystem.Attributes.Indexroot.IndexRoot)parent.attributes.ElementAt(2)).Children.Add(header);
                                                    ((FileSystem.Attributes.Indexroot.IndexRoot)parent.attributes.ElementAt(2)).numberOfChildren++;
                                                    header.parent = parent;

                                                    ntfsFS.FileRecordCount++;
                                                    ntfsFS.BytesOccupied  += 8;         // one child added
                                                    ntfsFS.BytesOccupied  += header.TotalEntrySize;
                                                    parent.UsedFolderSize += header.TotalEntrySize;
                                                }
                                                else
                                                {
                                                    Save(fsName, ntfsFS.Save());
                                                    throw new Exception("Volume is full!");
                                                }
                                            }

                                            else if (tmp == moveFolder && splitDestination.Length == 2)
                                            {
                                                Console.WriteLine("Copying failed!");
                                            }
                                        }
                                    }
                                    else
                                    {
                                        Console.WriteLine("Copying failed!");
                                    }
                                }
                            }
                            else
                            {
                                Console.WriteLine("Copying failed!");
                            }
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e);
                            Environment.Exit(0);
                        }

                        break;
                    }

                    case choice.mv:
                    {
                        string[] splitDestination = tokens[2].Split('\\');
                        if (splitDestination.Length > 2)
                        {
                            Console.WriteLine("Moving failed!");
                        }
                        else
                        {
                            FileRecordSegmentHeader movingFile = null;
                            foreach (var child in ((FileSystem.Attributes.Indexroot.IndexRoot)currectFolder.attributes.ElementAt(2)).Children)
                            {
                                if (((FileName)child.attributes.ElementAt(1)).Filename.Equals(tokens[1]))
                                {
                                    movingFile = child;
                                    break;
                                }
                            }

                            if (movingFile != null)
                            {
                                FileRecordSegmentHeader moveFolder = null;
                                FileRecordSegmentHeader tmp        = null;
                                foreach (var child in ((FileSystem.Attributes.Indexroot.IndexRoot)currectFolder.parent.attributes.ElementAt(2)).Children)
                                {
                                    if (((FileName)child.attributes.ElementAt(1)).Filename.Equals(splitDestination[0]))
                                    {
                                        tmp = moveFolder = child;
                                        break;
                                    }
                                }

                                if (moveFolder != null)
                                {
                                    if (splitDestination.Length == 2)
                                    {
                                        foreach (var child in ((FileSystem.Attributes.Indexroot.IndexRoot)tmp.attributes.ElementAt(2)).Children)
                                        {
                                            if (((FileName)child.attributes.ElementAt(1)).Filename.Equals(splitDestination[1]))
                                            {
                                                moveFolder = child;
                                                break;
                                            }
                                        }
                                    }
                                    if ((tmp != moveFolder && splitDestination.Length == 2) || (tmp == moveFolder && splitDestination.Length == 1))
                                    {
                                        ((FileSystem.Attributes.Indexroot.IndexRoot)currectFolder.attributes.ElementAt(2)).Children.Remove(movingFile);
                                        ((FileSystem.Attributes.Indexroot.IndexRoot)moveFolder.attributes.ElementAt(2)).Children.Add(movingFile);
                                        moveFolder.parent = moveFolder;
                                    }
                                    else if (tmp == moveFolder && splitDestination.Length == 2)
                                    {
                                        Console.WriteLine("Moving failed!");
                                    }
                                }
                                else
                                {
                                    Console.WriteLine("Moving failed!");
                                }
                            }
                            else
                            {
                                Console.WriteLine("Moving failed!");
                            }
                        }

                        break;
                    }

                    case choice.rename:
                    {
                        ntfsFS.changeName(currectFolder, tokens[1], tokens[2]);
                        break;
                    }

                    case choice.echo:
                    {
                        try
                        {
                            if (textCatch[1].Length < 64_000)
                            {
                                FileRecordSegmentHeader header = new FileRecordSegmentHeader();
                                FileRecordSegmentHeader parent = currectFolder;

                                header.CreateFileRecordHeader(Enums.MFTEntryFlags.FileRecordSegmentInUse, parent);

                                StandardInformation stdInfo = new StandardInformation();
                                stdInfo.CreateStandInfoFile(FileAttributes.Normal);
                                header.UsedEntrySize += stdInfo.RecordLength;

                                FileName fileName = new FileName();
                                fileName.CreateFileNameFile(tokens[1]);
                                header.UsedEntrySize += fileName.RecordLength;

                                if (textCatch.Length <= (header.TotalEntrySize - header.UsedEntrySize))
                                {
                                    fileName.AllocatedSize = header.TotalEntrySize - header.UsedEntrySize;
                                    fileName.RealSize      = (ulong)textCatch.Length;
                                    header.UsedEntrySize  += (uint)fileName.RealSize;

                                    Data data = new Data();
                                    //Array.Copy(textCatch, 0, data.DataBytes, 0, textCatch.Length);
                                    data.DataBytes = Encoding.ASCII.GetBytes(textCatch[1]);

                                    header.attributes.Add(stdInfo);
                                    header.attributes.Add(fileName);
                                    header.attributes.Add(data);

                                    if (header.TotalEntrySize < (ntfsFS.VolumeSize - ntfsFS.BytesOccupied) + 8)         // +8 for reference in folder
                                    {
                                        ntfsFS.mftHeaderRecord.Add(header);

                                        ((FileSystem.Attributes.Indexroot.IndexRoot)parent.attributes.ElementAt(2)).Children.Add(header);
                                        ((FileSystem.Attributes.Indexroot.IndexRoot)parent.attributes.ElementAt(2)).numberOfChildren++;
                                        header.parent = parent;

                                        ntfsFS.FileRecordCount++;
                                        ntfsFS.BytesOccupied  += 8;         // one child added
                                        ntfsFS.BytesOccupied  += header.TotalEntrySize;
                                        parent.UsedFolderSize += header.TotalEntrySize;
                                    }
                                    else
                                    {
                                        Save(fsName, ntfsFS.Save());
                                        throw new Exception("Volume is full!");
                                    }
                                }
                                else
                                {
                                    Console.WriteLine("File is too large!");
                                }
                            }
                            else
                            {
                                Console.WriteLine("Text file is larger than 64 KB!");
                            }
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e);
                            Environment.Exit(0);
                        }

                        break;
                    }

                    case choice.cat:
                    {
                        if (tokens[1].Contains(".txt"))
                        {
                            Console.WriteLine(System.Text.Encoding.ASCII.GetString(ntfsFS.searchDataInDirectory(currectFolder, tokens[1])));
                        }
                        else
                        {
                            Console.WriteLine("File is not *.txt!");
                        }
                        break;
                    }

                    case choice.rm:
                    {
                        FileRecordSegmentHeader deleteThisChild = null;
                        foreach (var child in ((IndexRoot)currectFolder.attributes.ElementAt(2)).Children)
                        {
                            if (((FileName)child.attributes.ElementAt(1)).Filename.Equals(tokens[1]))
                            {
                                deleteThisChild = child;
                                break;
                            }
                        }


                        if (deleteThisChild != null)
                        {
                            ntfsFS.BytesOccupied        -= 8;
                            ntfsFS.BytesOccupied        -= deleteThisChild.TotalEntrySize;
                            currectFolder.UsedFolderSize = deleteThisChild.TotalEntrySize;

                            if (deleteThisChild.Flags == Enums.MFTEntryFlags.FileRecordSegmentInUse)
                            {
                                ntfsFS.FileRecordCount--;
                            }
                            else
                            {
                                ntfsFS.DirectoryRecordCount--;
                            }

                            ((IndexRoot)currectFolder.attributes.ElementAt(2)).Children.Remove(deleteThisChild);
                            deleteThisChild.parent = null;
                        }
                        else
                        {
                            Console.WriteLine("File/Folder not found!");
                        }

                        break;
                    }

                    case choice.stat:
                    {
                        ntfsFS.printData(currectFolder, tokens[1]);
                        break;
                    }

                    case choice.cd:
                    {
                        if (!currentDir.Equals(tokens[1]))
                        {
                            var currectFolderNew = ntfsFS.FindFolder(currectFolder, tokens[1]);
                            if (currectFolderNew != null)
                            {
                                currectFolder = currectFolderNew;
                                if (currentDir.Equals(fsName))
                                {
                                    currentDir = subDir1 = tokens[1];
                                }
                                else if (currentDir.Equals(subDir1))
                                {
                                    currentDir = subDir2 = tokens[1];
                                }
                            }
                            else
                            {
                                Console.WriteLine("Directory '{0}' doesn't exist in '{1}'!", tokens[1], currentDir);
                            }
                        }
                        else
                        {
                            Console.WriteLine("This is not possible!");
                        }

                        break;
                    }

                    case choice.cd_remove:
                    {
                        if (currentDir == fsName)
                        {
                            // Save NtfsFileSystem to *.dat file
                            Save(fsName, ntfsFS.Save());
                            currentDir = string.Empty;
                            Environment.Exit(0);
                        }
                        else if (subDir2 != string.Empty)
                        {
                            var parentFolder = currectFolder.parent;
                            currectFolder = parentFolder;

                            subDir2    = string.Empty;
                            currentDir = subDir1;
                        }
                        else
                        {
                            currectFolder = ntfsFS.Root;
                            subDir1       = string.Empty;
                            currentDir    = fsName;
                        }

                        break;
                    }

                    case choice.cls:
                    {
                        Console.Clear();
                        break;
                    }

                    case choice.exit:
                    {
                        Save(fsName, ntfsFS.Save());
                        Environment.Exit(0);
                        break;
                    }
                    }
                }
                else
                {
                    Console.Write("{0}:\\>{1} {2}\n", fsName, "Unknown command.", message1);
                    continue;
                }
            }
        }