internal StandardInformationAttribute(INtfsContext context, AttributeRecord record) : base(context, record) { byte[] content = Utilities.ReadAll(Content); _si = new StandardInformation(); _si.ReadFrom(content, 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; }
private FileRecord(ref FileRecord[] recordArray, byte[] bytes, int offset, int bytesPerFileRecord, string volume, bool fast) { if (Encoding.ASCII.GetString(bytes, 0x00 + offset, 0x04) == "FILE") { OffsetOfUS = BitConverter.ToUInt16(bytes, 0x04 + offset); SizeOfUS = BitConverter.ToUInt16(bytes, 0x06 + offset); LogFileSequenceNumber = BitConverter.ToUInt64(bytes, 0x08 + offset); SequenceNumber = BitConverter.ToUInt16(bytes, 0x10 + offset); Hardlinks = BitConverter.ToUInt16(bytes, 0x12 + offset); OffsetOfAttribute = BitConverter.ToUInt16(bytes, 0x14 + offset); Flags = (FILE_RECORD_FLAG)BitConverter.ToUInt16(bytes, 0x16 + offset); Deleted = isDeleted(Flags); Directory = isDirectory(Flags); RealSize = BitConverter.ToInt32(bytes, 0x18 + offset); AllocatedSize = BitConverter.ToInt32(bytes, 0x1C + offset); ReferenceToBase = BitConverter.ToUInt64(bytes, 0x20 + offset); NextAttrId = BitConverter.ToUInt16(bytes, 0x28 + offset); RecordNumber = BitConverter.ToUInt32(bytes, 0x2C + offset); Attribute = FileRecordAttribute.GetInstances(bytes, OffsetOfAttribute + offset, bytesPerFileRecord, volume); #region AttributeProperties foreach (FileRecordAttribute attr in Attribute) { if (attr.Name == FileRecordAttribute.ATTR_TYPE.STANDARD_INFORMATION) { StandardInformation stdInfo = attr as StandardInformation; ModifiedTime = stdInfo.ModifiedTime; AccessedTime = stdInfo.AccessedTime; ChangedTime = stdInfo.ChangedTime; BornTime = stdInfo.BornTime; Permission = stdInfo.Permission; } else if (attr.Name == FileRecordAttribute.ATTR_TYPE.ATTRIBUTE_LIST) { if (!(Deleted)) { AttributeList attrList = null; List <FileRecordAttribute> list = new List <FileRecordAttribute>(); list.AddRange(Attribute); if (attr.NonResident) { attrList = new AttributeList(attr as NonResident); } else { attrList = attr as AttributeList; } foreach (AttrRef attribute in attrList.AttributeReference) { if (attribute.RecordNumber != RecordNumber) { FileRecord record = null; // Test if we have already parse the record if (recordArray[attribute.RecordNumber] != null) { record = recordArray[attribute.RecordNumber]; } else { // If not parse it and add it to the array record = new FileRecord(ref recordArray, bytes, bytesPerFileRecord * (int)attribute.RecordNumber, bytesPerFileRecord, volume, fast); recordArray[attribute.RecordNumber] = record; } // Add the attributes to the attribute array list.AddRange(record.Attribute); list.Remove(attr); } } Attribute = list.ToArray(); } } else if (attr.Name == FileRecordAttribute.ATTR_TYPE.FILE_NAME) { FileName fN = attr as FileName; if (!(fN.Namespace == 2)) { Name = fN.Filename; ParentSequenceNumber = fN.ParentSequenceNumber; ParentRecordNumber = fN.ParentRecordNumber; FNModifiedTime = fN.ModifiedTime; FNAccessedTime = fN.AccessedTime; FNChangedTime = fN.ChangedTime; FNBornTime = fN.BornTime; } } } #endregion AttributeProperties #region FullName if (fast) { FullName = Name; } else { StringBuilder sb = new StringBuilder(); string volLetter = Helper.GetVolumeLetter(volume); if (RecordNumber == 0) { sb.Append(volLetter); sb.Append('\\'); sb.Append(Name); FullName = sb.ToString(); } else if (RecordNumber == 5) { FullName = volLetter; } else { FileRecord parent = null; if (recordArray[this.ParentRecordNumber] != null) { parent = recordArray[this.ParentRecordNumber]; } else { parent = new FileRecord(ref recordArray, bytes, bytesPerFileRecord * (int)this.ParentRecordNumber, bytesPerFileRecord, volume, fast); recordArray[this.ParentRecordNumber] = parent; } if (parent.SequenceNumber == this.ParentSequenceNumber) { sb.Append(parent.FullName); } else { sb.Append(@"$OrphanFiles"); } if (Name != null) { sb.Append('\\'); FullName = sb.Append(Name).ToString(); } else { FullName = sb.ToString(); } } } #endregion FullName } }
private FileRecord(byte[] recordBytes, string volume, int bytesPerFileRecord, bool fast) { if (Encoding.ASCII.GetString(recordBytes, 0x00, 0x04) == "FILE") { VolumePath = volume; OffsetOfUS = BitConverter.ToUInt16(recordBytes, 0x04); SizeOfUS = BitConverter.ToUInt16(recordBytes, 0x06); LogFileSequenceNumber = BitConverter.ToUInt64(recordBytes, 0x08); SequenceNumber = BitConverter.ToUInt16(recordBytes, 0x10); Hardlinks = BitConverter.ToUInt16(recordBytes, 0x12); OffsetOfAttribute = BitConverter.ToUInt16(recordBytes, 0x14); Flags = (FILE_RECORD_FLAG)BitConverter.ToUInt16(recordBytes, 0x16); Deleted = isDeleted(Flags); Directory = isDirectory(Flags); RealSize = BitConverter.ToInt32(recordBytes, 0x18); AllocatedSize = BitConverter.ToInt32(recordBytes, 0x1C); ReferenceToBase = BitConverter.ToUInt64(recordBytes, 0x20); NextAttrId = BitConverter.ToUInt16(recordBytes, 40); RecordNumber = BitConverter.ToUInt32(recordBytes, 44); Attribute = FileRecordAttribute.GetInstances(recordBytes, OffsetOfAttribute, bytesPerFileRecord, volume); #region AttributeProperties foreach (FileRecordAttribute attr in Attribute) { if (attr.Name == FileRecordAttribute.ATTR_TYPE.STANDARD_INFORMATION) { StandardInformation stdInfo = attr as StandardInformation; ModifiedTime = stdInfo.ModifiedTime; AccessedTime = stdInfo.AccessedTime; ChangedTime = stdInfo.ChangedTime; BornTime = stdInfo.BornTime; Permission = stdInfo.Permission; } else if (attr.Name == FileRecordAttribute.ATTR_TYPE.ATTRIBUTE_LIST) { if (!(Deleted)) { AttributeList attrList = null; List <FileRecordAttribute> list = new List <FileRecordAttribute>(); list.AddRange(Attribute); if (attr.NonResident) { attrList = new AttributeList(attr as NonResident); } else { attrList = attr as AttributeList; } foreach (AttrRef attribute in attrList.AttributeReference) { if (attribute.RecordNumber != RecordNumber) { FileRecord record = FileRecord.Get(volume, (int)attribute.RecordNumber); list.AddRange(record.Attribute); list.Remove(attr); } } Attribute = list.ToArray(); } } else if (attr.Name == FileRecordAttribute.ATTR_TYPE.FILE_NAME) { FileName fN = attr as FileName; if (!(fN.Namespace == 2)) { Name = fN.Filename; ParentSequenceNumber = fN.ParentSequenceNumber; ParentRecordNumber = fN.ParentRecordNumber; FNModifiedTime = fN.ModifiedTime; FNAccessedTime = fN.AccessedTime; FNChangedTime = fN.ChangedTime; FNBornTime = fN.BornTime; } } } #endregion AttributeProperties #region FullName if (fast) { FullName = Name; } else { StringBuilder sb = new StringBuilder(); string volLetter = Helper.GetVolumeLetter(volume); if (RecordNumber == 0) { sb.Append(volLetter); sb.Append('\\'); sb.Append(Name); FullName = sb.ToString(); } else if (RecordNumber == 5) { FullName = volLetter; } else { FileRecord parent = new FileRecord(GetRecordBytes(volume, (int)ParentRecordNumber), volume, bytesPerFileRecord, false); if (parent.SequenceNumber == this.ParentSequenceNumber) { sb.Append(parent.FullName); } else { sb.Append(@"$OrphanFiles"); } if (Name != null) { sb.Append('\\'); FullName = sb.Append(Name).ToString(); } else { FullName = sb.ToString(); } } } #endregion FullName } }
/// <summary> /// Begin the process of interpreting MFT data /// </summary> private unsafe Node[] ProcessMft() { //64 KB seems to be optimal for Windows XP, Vista is happier with 256KB... uint bufferSize = (Environment.OSVersion.Version.Major >= 6 ? 256u : 64u) * 1024; byte[] data = new byte[bufferSize]; fixed(byte *buffer = data) { //Read the $MFT record from disk into memory, which is always the first record in the MFT. ReadFile(buffer, _diskInfo.BytesPerMftRecord, _diskInfo.MftStartLcn * _diskInfo.BytesPerSector * _diskInfo.SectorsPerCluster); //Fixup the raw data from disk. This will also test if it's a valid $MFT record. FixupRawMftdata(buffer, _diskInfo.BytesPerMftRecord); List <Stream> mftStreams = new List <Stream>(); if ((_retrieveMode & RetrieveMode.StandardInformations) == RetrieveMode.StandardInformations) { _standardInformations = new StandardInformation[1]; //allocate some space for $MFT record } Node mftNode; if (!ProcessMftRecord(buffer, _diskInfo.BytesPerMftRecord, 0, out mftNode, mftStreams, true)) { throw new Exception("Can't interpret Mft Record"); } //the bitmap data contains all used inodes on the disk _bitmapData = ProcessBitmapData(mftStreams); OnBitmapDataAvailable(); Stream dataStream = SearchStream(mftStreams, AttributeType.AttributeData); UInt32 maxInode = (UInt32)_bitmapData.Length * 8; if (maxInode > (UInt32)(dataStream.Size / _diskInfo.BytesPerMftRecord)) { maxInode = (UInt32)(dataStream.Size / _diskInfo.BytesPerMftRecord); } Node[] nodes = new Node[maxInode]; nodes[0] = mftNode; if ((_retrieveMode & RetrieveMode.StandardInformations) == RetrieveMode.StandardInformations) { StandardInformation mftRecordInformation = _standardInformations[0]; _standardInformations = new StandardInformation[maxInode]; _standardInformations[0] = mftRecordInformation; } if ((_retrieveMode & RetrieveMode.Streams) == RetrieveMode.Streams) { _streams = new Stream[maxInode][]; } /* Read and process all the records in the MFT. The records are read into a * buffer and then given one by one to the InterpretMftRecord() subroutine. */ UInt64 BlockStart = 0, BlockEnd = 0; UInt64 RealVcn = 0, Vcn = 0; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); ulong totalBytesRead = 0; int fragmentIndex = 0; int fragmentCount = dataStream.Fragments.Count; for (UInt32 nodeIndex = 1; nodeIndex < maxInode; nodeIndex++) { // Ignore the Inode if the bitmap says it's not in use. if ((_bitmapData[nodeIndex >> 3] & BitmapMasks[nodeIndex % 8]) == 0) { continue; } if (nodeIndex >= BlockEnd) { if (!ReadNextChunk( buffer, bufferSize, nodeIndex, fragmentIndex, dataStream, ref BlockStart, ref BlockEnd, ref Vcn, ref RealVcn)) { break; } totalBytesRead += (BlockEnd - BlockStart) * _diskInfo.BytesPerMftRecord; } FixupRawMftdata( buffer + (nodeIndex - BlockStart) * _diskInfo.BytesPerMftRecord, _diskInfo.BytesPerMftRecord ); List <Stream> streams = null; if ((_retrieveMode & RetrieveMode.Streams) == RetrieveMode.Streams) { streams = new List <Stream>(); } Node newNode; if (!ProcessMftRecord( buffer + (nodeIndex - BlockStart) * _diskInfo.BytesPerMftRecord, _diskInfo.BytesPerMftRecord, nodeIndex, out newNode, streams, false)) { continue; } nodes[nodeIndex] = newNode; if (streams != null) { _streams[nodeIndex] = streams.ToArray(); } } stopwatch.Stop(); Trace.WriteLine( string.Format( "{0:F3} MB of volume metadata has been read in {1:F3} s at {2:F3} MB/s", (float)totalBytesRead / (1024 * 1024), (float)stopwatch.Elapsed.TotalSeconds, ((float)totalBytesRead / (1024 * 1024)) / stopwatch.Elapsed.TotalSeconds ) ); return(nodes); } }
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; } } }
/// <summary> /// Process each attributes and gather information when necessary /// </summary> private unsafe void ProcessAttributes(ref Node node, UInt32 nodeIndex, byte *ptr, UInt64 BufLength, UInt16 instance, int depth, List <Stream> streams, bool isMftNode) { int currentNameType = -1; Attribute *attribute = null; for (uint AttributeOffset = 0; AttributeOffset < BufLength; AttributeOffset = AttributeOffset + attribute->Length) { attribute = (Attribute *)(ptr + AttributeOffset); // exit the loop if end-marker. if ((AttributeOffset + 4 <= BufLength) && (*(UInt32 *)attribute == 0xFFFFFFFF)) { break; } //make sure we did read the data correctly if ((AttributeOffset + 4 > BufLength) || attribute->Length < 3 || (AttributeOffset + attribute->Length > BufLength)) { throw new Exception("Error: attribute in Inode %I64u is bigger than the data, the MFT may be corrupt."); } //attributes list needs to be processed at the end if (attribute->AttributeType == AttributeType.AttributeAttributeList) { continue; } /* If the Instance does not equal the AttributeNumber then ignore the attribute. * This is used when an AttributeList is being processed and we only want a specific * instance. */ if ((instance != 65535) && (instance != attribute->AttributeNumber)) { continue; } if (attribute->Nonresident == 0) { ResidentAttribute *residentAttribute = (ResidentAttribute *)attribute; switch (attribute->AttributeType) { case AttributeType.AttributeFileName: AttributeFileName *attributeFileName = (AttributeFileName *)(ptr + AttributeOffset + residentAttribute->ValueOffset); if (attributeFileName->ParentDirectory.InodeNumberHighPart > 0) { throw new NotSupportedException("48 bits inode are not supported to reduce memory footprint."); } if (node.Size == 0) //missing file size { node.Size = attributeFileName->DataSize; //set file size if not already set } if (node.NameIndex == 0) { currentNameType = (int)attributeFileName->NameType; node.NameIndex = GetNameIndex(new string(&attributeFileName->Name, 0, attributeFileName->NameLength)); node.ParentNodeIndex = attributeFileName->ParentDirectory.InodeNumberLowPart; } else { int attributeNameType = (int)attributeFileName->NameType; if (attributeNameType == 0 || currentNameType == 2) { currentNameType = attributeNameType; node.NameIndex = GetNameIndex(new string(&attributeFileName->Name, 0, attributeFileName->NameLength)); node.ParentNodeIndex = attributeFileName->ParentDirectory.InodeNumberLowPart; } } break; case AttributeType.AttributeStandardInformation: AttributeStandardInformation *attributeStandardInformation = (AttributeStandardInformation *)(ptr + AttributeOffset + residentAttribute->ValueOffset); node.Attributes |= (Attributes)attributeStandardInformation->FileAttributes; if ((_retrieveMode & RetrieveMode.StandardInformations) == RetrieveMode.StandardInformations) { _standardInformations[nodeIndex] = new StandardInformation( attributeStandardInformation->CreationTime, attributeStandardInformation->FileChangeTime, attributeStandardInformation->LastAccessTime, attributeStandardInformation->MftChangeTime ); } break; case AttributeType.AttributeData: node.Size = residentAttribute->ValueLength; break; } } else { NonResidentAttribute *nonResidentAttribute = (NonResidentAttribute *)attribute; //save the length (number of bytes) of the data. if (attribute->AttributeType == AttributeType.AttributeData && node.Size == 0) { node.Size = nonResidentAttribute->DataSize; } if (streams != null) { //extract the stream name int streamNameIndex = 0; if (attribute->NameLength > 0) { streamNameIndex = GetNameIndex(new string((char *)(ptr + AttributeOffset + attribute->NameOffset), 0, (int)attribute->NameLength)); } //find or create the stream Stream stream = SearchStream(streams, attribute->AttributeType, streamNameIndex); if (stream == null) { stream = new Stream(streamNameIndex, attribute->AttributeType, nonResidentAttribute->DataSize); streams.Add(stream); } else if (stream.Size == 0) { stream.Size = nonResidentAttribute->DataSize; } //we need the fragment of the MFTNode so retrieve them this time //even if fragments aren't normally read if (isMftNode || (_retrieveMode & RetrieveMode.Fragments) == RetrieveMode.Fragments) { ProcessFragments( ref node, stream, ptr + AttributeOffset + nonResidentAttribute->RunArrayOffset, attribute->Length - nonResidentAttribute->RunArrayOffset, nonResidentAttribute->StartingVcn ); } } } } if (streams != null && streams.Count > 0) { node.Size = streams[0].Size; } }
private ProviderDocument CreateStandardProviderDocument(CoreProvider provider, StandardInformation standardInformation, List <DeliveryInformation> deliveryInformation) { try { var standardProvider = new ProviderDocument(ElasticsearchDocumentTypes.PROVIDER_STANDARD_DOCUMENT) { StandardCode = standardInformation.Code, RegulatedStandard = standardInformation.RegulatedStandard }; PopulateDocumentSharedProperties(standardProvider, provider, standardInformation, deliveryInformation); return(standardProvider); } catch (Exception ex) when(ex is ArgumentNullException || ex is NullReferenceException) { throw new MappingException("Unable to map to Standard Provider Document", ex); } }
public ProviderDocument CreateStandardProviderDocument(CoreProvider provider, StandardInformation standardInformation, IEnumerable <DeliveryInformation> deliveryInformation) { return(CreateStandardProviderDocument(provider, standardInformation, deliveryInformation.ToList())); }
public ProviderDocument CreateStandardProviderDocument(CoreProvider provider, StandardInformation standardInformation, DeliveryInformation deliveryInformation) { return(CreateStandardProviderDocument(provider, standardInformation, new List <DeliveryInformation> { deliveryInformation })); }
/// <summary> /// Initializes a new instance of the <see cref="EncryptedFile"/> class. /// This constructor is used when encrypted file is created. /// </summary> /// <param name="fileName">Full name of the original file.</param> /// <param name="userId">Id of the file owner.</param> /// <param name="algorithmNameSignature">Full name of the algorithm used for file encryption.</param> /// <param name="hashAlgorithmName">Name of the hashing algorithm used to create a file signature.</param> /// <param name="ownerPublicKey">Public RSA key of the file owner.</param> /// <param name="ownerPrivateKey">Private RSA key of the file owner.</param> public EncryptedFile(string fileName, uint userId, string algorithmNameSignature, string hashAlgorithmName, RSAParameters ownerPublicKey, RSAParameters ownerPrivateKey) { Headers[0] = new StandardInformation(userId); Headers[1] = new SecurityDescriptor((int)userId, algorithmNameSignature, hashAlgorithmName, ownerPublicKey); NameEncryption(fileName, new AesAlgorithm(((SecurityDescriptor)Headers[1]).GetKey((int)userId, ownerPrivateKey), ((SecurityDescriptor)Headers[1]).IV, "OFB")); }