public FileNameRecord Clone() { FileNameRecord clone = (FileNameRecord)this.MemberwiseClone(); clone.ParentDirectory = this.ParentDirectory.Clone(); return(clone); }
public static FileSystemEntry ToFileSystemEntry(string path, FileNameRecord fileNameRecord) { ulong size = fileNameRecord.FileSize; bool isDirectory = fileNameRecord.IsDirectory; FileAttributes attributes = fileNameRecord.FileAttributes; bool isHidden = (attributes & FileAttributes.Hidden) > 0; bool isReadonly = (attributes & FileAttributes.Readonly) > 0; bool isArchived = (attributes & FileAttributes.Archive) > 0; return(new FileSystemEntry(path, fileNameRecord.FileName, isDirectory, size, fileNameRecord.CreationTime, fileNameRecord.ModificationTime, fileNameRecord.LastAccessTime, isHidden, isReadonly, isArchived)); }
public FileNameIndexEntry(byte[] buffer, int offset) { FileReference = new MftSegmentReference(buffer, offset + 0x00); RecordLength = LittleEndianConverter.ToUInt16(buffer, offset + 0x08); FileNameOffset = LittleEndianConverter.ToUInt16(buffer, offset + 0x0A); IndexFlags = (IndexEntryFlags)LittleEndianConverter.ToUInt16(buffer, offset + 0x0C); if (RecordLength > 16)// otherwise it's the last record { Record = new FileNameRecord(buffer, offset + 0x10); } }
public KeyValuePairList <MftSegmentReference, FileNameRecord> GetAllFileNameRecords() { KeyValuePairList <MftSegmentReference, FileNameRecord> result = new KeyValuePairList <MftSegmentReference, FileNameRecord>(); KeyValuePairList <MftSegmentReference, byte[]> entries = GetAllEntries(); foreach (KeyValuePair <MftSegmentReference, byte[]> entry in entries) { FileNameRecord fileNameRecord = new FileNameRecord(entry.Value, 0); result.Add(entry.Key, fileNameRecord); } return(result); }
public MftSegmentReference FindFileNameRecordSegmentReference(string fileName) { byte[] key = FileNameRecord.GetIndexKeyBytes(fileName); KeyValuePair <MftSegmentReference, byte[]>?entry = FindEntry(key); if (entry != null) { return(entry.Value.Key); } else { return(null); } }
public KeyValuePairList <MftSegmentReference, FileNameRecord> GetAllEntries(NTFSVolume volume, IndexRootRecord rootRecord) { KeyValuePairList <MftSegmentReference, FileNameRecord> result = new KeyValuePairList <MftSegmentReference, FileNameRecord>(); List <IndexNodeEntry> parents = new List <IndexNodeEntry>(rootRecord.IndexEntries); List <IndexRecord> leaves = new List <IndexRecord>(); int parentIndex = 0; while (parentIndex < parents.Count) { IndexNodeEntry parent = parents[parentIndex]; byte[] clusters = this.ReadDataClusters(volume, parent.SubnodeVCN, rootRecord.ClustersPerIndexRecord); IndexRecord record = new IndexRecord(clusters, 0); if (record.HasChildren) { foreach (IndexNodeEntry node in record.IndexEntries) { parents.Add(node); } } else { leaves.Add(record); } parentIndex++; } foreach (IndexNodeEntry node in parents) { if (!node.IsLastEntry) { // Some of the tree data in NTFS is contained in non-leaf keys FileNameRecord parentRecord = new FileNameRecord(node.Key, 0); result.Add(node.SegmentReference, parentRecord); } } foreach (IndexRecord record in leaves) { foreach (FileNameIndexEntry entry in record.FileNameEntries) { result.Add(entry.FileReference, entry.Record); } } result.Sort(Compare); return(result); }
private List <FileNameRecord> GetFileNameRecords() { List <FileNameRecord> result = new List <FileNameRecord>(); foreach (AttributeRecord attribute in this.Attributes) { if (attribute is FileNameAttributeRecord) { FileNameRecord fileNameRecord = ((FileNameAttributeRecord)attribute).Record; result.Add(fileNameRecord); } } return(result); }
/// <param name="fileNameNamespace">POSIX or Win32 or DOS, multiple flags are not supported</param> private FileNameRecord GetFileNameRecord(FileNameFlags fileNameNamespace) { foreach (AttributeRecord attribute in this.Attributes) { if (attribute is FileNameAttributeRecord) { FileNameRecord fileNameRecord = ((FileNameAttributeRecord)attribute).Record; if (fileNameRecord.IsInNamespace(fileNameNamespace)) { return(fileNameRecord); } } } return(null); }
public FileNameRecord GetFileNameRecord(FilenameNamespace filenameNamespace) { foreach (AttributeRecord attribute in this.Attributes) { if (attribute is FileNameAttributeRecord) { FileNameRecord fileNameAttribute = ((FileNameAttributeRecord)attribute).Record; if (fileNameAttribute.Namespace == filenameNamespace) { return(fileNameAttribute); } } } return(null); }
public static List <FileNameRecord> GenerateFileNameRecords(MftSegmentReference parentDirectory, string fileName, bool isDirectory, bool generateDosName, IndexData parentDirectoryIndex, DateTime creationTime, DateTime modificationTime, DateTime mftModificationTime, DateTime lastAccessTime, ulong allocatedLength, ulong fileSize, FileAttributes fileAttributes, ushort packedEASize) { FileNameRecord fileNameRecord = new FileNameRecord(parentDirectory, fileName, isDirectory, creationTime); fileNameRecord.ParentDirectory = parentDirectory; fileNameRecord.CreationTime = creationTime; fileNameRecord.ModificationTime = modificationTime; fileNameRecord.MftModificationTime = mftModificationTime; fileNameRecord.LastAccessTime = lastAccessTime; fileNameRecord.AllocatedLength = allocatedLength; fileNameRecord.FileSize = fileSize; fileNameRecord.FileAttributes = fileAttributes; fileNameRecord.PackedEASize = packedEASize; fileNameRecord.IsDirectory = isDirectory; fileNameRecord.FileName = fileName; bool createDosOnlyRecord = false; if (generateDosName) { fileNameRecord.Flags = FileNameFlags.Win32; if (DosFileNameHelper.IsValidDosFileName(fileName)) { fileNameRecord.Flags |= FileNameFlags.DOS; } else { createDosOnlyRecord = true; } } else { // This is similar to Windows 8.1, When FileNameFlags.Win32 is set, Windows Server 2003's CHKDSK expects to find a record with FileNameFlags.DOS set. fileNameRecord.Flags = FileNameFlags.POSIX; } List <FileNameRecord> result = new List <FileNameRecord>(); result.Add(fileNameRecord); if (createDosOnlyRecord) { string dosFileName = DosFileNameHelper.GenerateDosName(parentDirectoryIndex, fileName); FileNameRecord dosOnlyRecord = new FileNameRecord(parentDirectory, dosFileName, isDirectory, creationTime); dosOnlyRecord.Flags = FileNameFlags.DOS; result.Add(dosOnlyRecord); } return(result); }
public KeyValuePair <MftSegmentReference, FileNameRecord>?FindFileNameRecord(string fileName) { byte[] key = FileNameRecord.GetIndexKeyBytes(fileName); KeyValuePair <MftSegmentReference, byte[]>?entry = FindEntry(key); if (entry != null) { MftSegmentReference fileReference = entry.Value.Key; FileNameRecord fileNameRecord = new FileNameRecord(entry.Value.Value, 0); return(new KeyValuePair <MftSegmentReference, FileNameRecord>(fileReference, fileNameRecord)); } else { return(null); } }
public static int Compare(byte[] key1, byte[] key2, CollationRule collationRule) { switch (collationRule) { case CollationRule.Filename: { string str1 = FileNameRecord.ReadFileName(key1, 0); string str2 = FileNameRecord.ReadFileName(key2, 0); return(String.Compare(str1, str2, StringComparison.OrdinalIgnoreCase)); } case CollationRule.UnicodeString: { string str1 = Encoding.Unicode.GetString(key1); string str2 = Encoding.Unicode.GetString(key2); return(String.Compare(str1, str2, StringComparison.OrdinalIgnoreCase)); } default: throw new NotImplementedException(); } }
public static NTFSVolume Format(Volume volume, byte majorNTFSVersion, byte minorNTFSVersion, int bytesPerCluster, string volumeLabel) { if (volumeLabel.Length > VolumeNameRecord.MaxVolumeNameLength) { throw new InvalidNameException(); } if (bytesPerCluster % volume.BytesPerSector > 0) { throw new ArgumentException("bytesPerCluster must be a multiple of volume.BytesPerSector"); } if (majorNTFSVersion != 3 || (minorNTFSVersion != 0 && minorNTFSVersion != 1)) { throw new NotSupportedException(); } long volumeClusterCount = (volume.Size - NTFSBootRecord.Length) / bytesPerCluster; // We wish to make WriteVolumeBitmap() as simple as possible so we use a multiple of ExtendGranularity to avoid having to set bits at the end of the bitmap volumeClusterCount = (long)Math.Floor((double)volumeClusterCount / (VolumeBitmap.ExtendGranularity * 8)) * (VolumeBitmap.ExtendGranularity * 8); int sectorsPerCluster = bytesPerCluster / volume.BytesPerSector; int bytesPerFileRecordSegment = 1024; // Supported values are 1024 or 4096 (when formatted with /L) int bytesPerIndexRecord = 4096; // Legal values are 1024, 2048 or 4096. NTFS v5.1 driver will always use 4096. int bootSegmentFileSize = 8192; int bootSegmentAllocatedLength = (int)Math.Ceiling((double)bootSegmentFileSize / bytesPerCluster) * bytesPerCluster; FileNameRecord bootFileNameRecord = new FileNameRecord(MasterFileTable.RootDirSegmentReference, "$Boot", false, DateTime.Now); bootFileNameRecord.AllocatedLength = (ulong)bootSegmentAllocatedLength; bootFileNameRecord.FileSize = (ulong)bootSegmentFileSize; bootFileNameRecord.FileAttributes = FileAttributes.Hidden | FileAttributes.System; FileRecordSegment bootSegment = CreateBaseRecordSegment(MasterFileTable.BootSegmentNumber, (ushort)MasterFileTable.BootSegmentNumber, bootFileNameRecord); bootSegment.ReferenceCount = 1; NonResidentAttributeRecord bootDataRecord = (NonResidentAttributeRecord)bootSegment.CreateAttributeRecord(AttributeType.Data, String.Empty, false); bootDataRecord.AllocatedLength = (ulong)bootSegmentAllocatedLength; bootDataRecord.FileSize = (ulong)bootSegmentFileSize; bootDataRecord.ValidDataLength = (ulong)bootSegmentFileSize; int bootDataClusterCount = (int)Math.Ceiling((double)8192 / bytesPerCluster); long bootDataStartLCN = 0; bootDataRecord.DataRunSequence.Add(new DataRun(bootDataClusterCount, bootDataStartLCN)); bootDataRecord.HighestVCN = bootDataClusterCount - 1; long volumeBitmapFileSize = (long)Math.Ceiling((double)volumeClusterCount / (VolumeBitmap.ExtendGranularity * 8)) * VolumeBitmap.ExtendGranularity; long numberOfVolumeBitmapClusters = (long)Math.Ceiling((double)volumeBitmapFileSize / bytesPerCluster); long volumeBitmapAllocatedLength = numberOfVolumeBitmapClusters * bytesPerCluster; FileNameRecord volumeBitmapFileNameRecord = new FileNameRecord(MasterFileTable.RootDirSegmentReference, "$Bitmap", false, DateTime.Now); volumeBitmapFileNameRecord.AllocatedLength = (ulong)volumeBitmapAllocatedLength; volumeBitmapFileNameRecord.FileSize = (ulong)volumeBitmapFileSize; volumeBitmapFileNameRecord.FileAttributes = FileAttributes.Hidden | FileAttributes.System; FileRecordSegment volumeBitmapSegment = CreateBaseRecordSegment(MasterFileTable.BitmapSegmentNumber, (ushort)MasterFileTable.BitmapSegmentNumber, volumeBitmapFileNameRecord); volumeBitmapSegment.ReferenceCount = 1; NonResidentAttributeRecord volumeBitmapDataRecord = (NonResidentAttributeRecord)volumeBitmapSegment.CreateAttributeRecord(AttributeType.Data, String.Empty, false); long volumeBitmapStartLCN = bootDataClusterCount; volumeBitmapDataRecord.AllocatedLength = (ulong)volumeBitmapAllocatedLength; volumeBitmapDataRecord.FileSize = (ulong)volumeBitmapFileSize; volumeBitmapDataRecord.ValidDataLength = (ulong)volumeBitmapFileSize; volumeBitmapDataRecord.DataRunSequence.Add(new DataRun(numberOfVolumeBitmapClusters, volumeBitmapStartLCN)); volumeBitmapDataRecord.HighestVCN = numberOfVolumeBitmapClusters - 1; int numberOfMftRecords = 64; int mftDataLength = numberOfMftRecords * bytesPerFileRecordSegment; FileNameRecord mftFileNameRecord = new FileNameRecord(MasterFileTable.RootDirSegmentReference, "$MFT", false, DateTime.Now); mftFileNameRecord.AllocatedLength = (ulong)mftDataLength; mftFileNameRecord.FileSize = (ulong)mftDataLength; mftFileNameRecord.FileAttributes = FileAttributes.Hidden | FileAttributes.System; FileRecordSegment mftSegment = CreateBaseRecordSegment(MasterFileTable.MasterFileTableSegmentNumber, 1, mftFileNameRecord); mftSegment.ReferenceCount = 1; NonResidentAttributeRecord mftDataRecord = (NonResidentAttributeRecord)mftSegment.CreateAttributeRecord(AttributeType.Data, String.Empty, false); mftDataRecord.AllocatedLength = (ulong)mftDataLength; mftDataRecord.FileSize = (ulong)mftDataLength; mftDataRecord.ValidDataLength = (ulong)mftDataLength; int mftDataClusterCount = (int)Math.Ceiling((double)mftDataLength / bytesPerCluster); long mftDataStartLCN = volumeBitmapStartLCN + numberOfVolumeBitmapClusters; mftDataRecord.DataRunSequence.Add(new DataRun(mftDataClusterCount, mftDataStartLCN)); mftDataRecord.HighestVCN = mftDataClusterCount - 1; NonResidentAttributeRecord mftBitmapRecord = (NonResidentAttributeRecord)mftSegment.CreateAttributeRecord(AttributeType.Bitmap, String.Empty, false); int mftBitmapLength = (int)Math.Ceiling((double)numberOfMftRecords / (BitmapData.ExtendGranularity * 8)) * BitmapData.ExtendGranularity; int mftBitmapClusterCount = (int)Math.Ceiling((double)mftBitmapLength / bytesPerCluster); mftBitmapRecord.AllocatedLength = (ulong)(mftBitmapClusterCount * bytesPerCluster); mftBitmapRecord.FileSize = (ulong)mftBitmapLength; mftBitmapRecord.ValidDataLength = (ulong)mftBitmapLength; long mftBitmapStartLCN = mftDataStartLCN + mftDataClusterCount; mftBitmapRecord.DataRunSequence.Add(new DataRun(mftBitmapClusterCount, mftBitmapStartLCN)); mftBitmapRecord.HighestVCN = 0; int bytesPerLogPage = 4096; int logFileDataLength = 512 * bytesPerLogPage; FileNameRecord logFileNameRecord = new FileNameRecord(MasterFileTable.RootDirSegmentReference, "$LogFile", false, DateTime.Now); logFileNameRecord.AllocatedLength = (ulong)logFileDataLength; logFileNameRecord.FileSize = (ulong)logFileDataLength; logFileNameRecord.FileAttributes = FileAttributes.Hidden | FileAttributes.System; FileRecordSegment logFileSegment = CreateBaseRecordSegment(MasterFileTable.LogFileSegmentNumber, (ushort)MasterFileTable.LogFileSegmentNumber, logFileNameRecord); logFileSegment.ReferenceCount = 1; NonResidentAttributeRecord logFileDataRecord = (NonResidentAttributeRecord)logFileSegment.CreateAttributeRecord(AttributeType.Data, String.Empty, false); logFileDataRecord.AllocatedLength = (ulong)logFileDataLength; logFileDataRecord.FileSize = (ulong)logFileDataLength; logFileDataRecord.ValidDataLength = (ulong)logFileDataLength; int logFileClusterCount = (int)Math.Ceiling((double)logFileDataLength / bytesPerCluster); long logFileStartLCN = mftBitmapStartLCN + mftBitmapClusterCount; logFileDataRecord.DataRunSequence.Add(new DataRun(logFileClusterCount, logFileStartLCN)); logFileDataRecord.HighestVCN = logFileClusterCount - 1; FileNameRecord volumeFileNameRecord = new FileNameRecord(MasterFileTable.RootDirSegmentReference, "$Volume", false, DateTime.Now); volumeFileNameRecord.FileAttributes = FileAttributes.Hidden | FileAttributes.System; FileRecordSegment volumeSegment = CreateBaseRecordSegment(MasterFileTable.VolumeSegmentNumber, (ushort)MasterFileTable.VolumeSegmentNumber, volumeFileNameRecord); volumeSegment.ReferenceCount = 1; VolumeNameRecord volumeName = (VolumeNameRecord)volumeSegment.CreateAttributeRecord(AttributeType.VolumeName, String.Empty); volumeName.VolumeName = volumeLabel; VolumeInformationRecord volumeInformation = (VolumeInformationRecord)volumeSegment.CreateAttributeRecord(AttributeType.VolumeInformation, String.Empty); volumeInformation.MajorVersion = majorNTFSVersion; volumeInformation.MinorVersion = minorNTFSVersion; volumeSegment.CreateAttributeRecord(AttributeType.Data, String.Empty); long logFileDataStartSector = logFileStartLCN * sectorsPerCluster; WriteLogFile(volume, logFileDataStartSector, logFileDataLength, bytesPerLogPage); long attributeDefinitionStartLCN = logFileStartLCN + logFileClusterCount; long attributeDefinitionStartSector = attributeDefinitionStartLCN * sectorsPerCluster; int attributeDefinitionLength = WriteAttributeDefinition(volume, attributeDefinitionStartSector, bytesPerCluster); int attributeDefinitionClusterCount = (int)Math.Ceiling((double)attributeDefinitionLength / bytesPerCluster); int attributeDefinitionAllocatedLength = attributeDefinitionClusterCount * bytesPerCluster; FileNameRecord attributeDefinitionFileNameRecord = new FileNameRecord(MasterFileTable.RootDirSegmentReference, "$AttrDef", false, DateTime.Now); attributeDefinitionFileNameRecord.AllocatedLength = (ulong)attributeDefinitionAllocatedLength; attributeDefinitionFileNameRecord.FileSize = (ulong)attributeDefinitionLength; attributeDefinitionFileNameRecord.FileAttributes = FileAttributes.Hidden | FileAttributes.System; FileRecordSegment attributeDefinitionSegment = CreateBaseRecordSegment(MasterFileTable.AttrDefSegmentNumber, (ushort)MasterFileTable.AttrDefSegmentNumber, attributeDefinitionFileNameRecord); attributeDefinitionSegment.ReferenceCount = 1; NonResidentAttributeRecord attributeDefinitionDataRecord = (NonResidentAttributeRecord)attributeDefinitionSegment.CreateAttributeRecord(AttributeType.Data, String.Empty, false); attributeDefinitionDataRecord.AllocatedLength = (ulong)attributeDefinitionAllocatedLength; attributeDefinitionDataRecord.FileSize = (ulong)attributeDefinitionLength; attributeDefinitionDataRecord.ValidDataLength = (ulong)attributeDefinitionLength; attributeDefinitionDataRecord.DataRunSequence.Add(new DataRun(attributeDefinitionClusterCount, attributeDefinitionStartLCN)); attributeDefinitionDataRecord.HighestVCN = attributeDefinitionClusterCount - 1; FileNameRecord badClustersFileNameRecord = new FileNameRecord(MasterFileTable.RootDirSegmentReference, "$BadClus", false, DateTime.Now); badClustersFileNameRecord.FileAttributes = FileAttributes.Hidden | FileAttributes.System; FileRecordSegment badClustersSegment = CreateBaseRecordSegment(MasterFileTable.BadClusSegmentNumber, (ushort)MasterFileTable.BadClusSegmentNumber, badClustersFileNameRecord); badClustersSegment.ReferenceCount = 1; badClustersSegment.CreateAttributeRecord(AttributeType.Data, String.Empty); NonResidentAttributeRecord badClustersData = (NonResidentAttributeRecord)badClustersSegment.CreateAttributeRecord(AttributeType.Data, "$Bad", false); DataRun volumeDataRun = new DataRun(); volumeDataRun.RunLength = volumeClusterCount; volumeDataRun.IsSparse = true; badClustersData.DataRunSequence.Add(volumeDataRun); badClustersData.HighestVCN = volumeClusterCount - 1; badClustersData.AllocatedLength = (ulong)(volumeClusterCount * bytesPerCluster); badClustersData.FileSize = 0; badClustersData.ValidDataLength = 0; FileNameRecord secureFileNameRecord = new FileNameRecord(MasterFileTable.RootDirSegmentReference, "$Secure", false, DateTime.Now); secureFileNameRecord.FileAttributes = FileAttributes.Hidden | FileAttributes.System; FileRecordSegment secureSegment = CreateBaseRecordSegment(MasterFileTable.SecureSegmentNumber, (ushort)MasterFileTable.SecureSegmentNumber, secureFileNameRecord); secureSegment.IsSpecialIndex = true; secureSegment.ReferenceCount = 1; secureSegment.CreateAttributeRecord(AttributeType.Data, "$SDS"); IndexRootRecord sdh = (IndexRootRecord)secureSegment.CreateAttributeRecord(AttributeType.IndexRoot, "$SDH"); IndexHelper.InitializeIndexRoot(sdh, AttributeType.None, CollationRule.SecurityHash, bytesPerIndexRecord, bytesPerCluster); IndexRootRecord sii = (IndexRootRecord)secureSegment.CreateAttributeRecord(AttributeType.IndexRoot, "$SII"); IndexHelper.InitializeIndexRoot(sii, AttributeType.None, CollationRule.UnsignedLong, bytesPerIndexRecord, bytesPerCluster); int upcaseDataClusterCount = (int)Math.Ceiling((double)UpcaseFileLength / bytesPerCluster); FileNameRecord upcaseFileNameRecord = new FileNameRecord(MasterFileTable.RootDirSegmentReference, "$UpCase", false, DateTime.Now); upcaseFileNameRecord.AllocatedLength = UpcaseFileLength; upcaseFileNameRecord.FileSize = UpcaseFileLength; upcaseFileNameRecord.FileAttributes = FileAttributes.Hidden | FileAttributes.System; FileRecordSegment upcaseSegment = CreateBaseRecordSegment(MasterFileTable.UpCaseSegmentNumber, (ushort)MasterFileTable.UpCaseSegmentNumber, upcaseFileNameRecord); upcaseSegment.ReferenceCount = 1; NonResidentAttributeRecord upcaseFileDataRecord = (NonResidentAttributeRecord)upcaseSegment.CreateAttributeRecord(AttributeType.Data, String.Empty, false); upcaseFileDataRecord.AllocatedLength = UpcaseFileLength; upcaseFileDataRecord.FileSize = UpcaseFileLength; upcaseFileDataRecord.ValidDataLength = UpcaseFileLength; long upcaseDataStartLCN = attributeDefinitionStartLCN + attributeDefinitionClusterCount; upcaseFileDataRecord.DataRunSequence.Add(new DataRun(upcaseDataClusterCount, upcaseDataStartLCN)); upcaseFileDataRecord.HighestVCN = upcaseDataClusterCount - 1; FileNameRecord extendFileNameRecord = new FileNameRecord(MasterFileTable.RootDirSegmentReference, "$Extend", true, DateTime.Now); extendFileNameRecord.FileAttributes = FileAttributes.System | FileAttributes.Hidden | FileAttributes.FileNameIndexPresent; FileRecordSegment extendSegment = CreateBaseRecordSegment(MasterFileTable.ExtendSegmentNumber, (ushort)MasterFileTable.ExtendSegmentNumber, extendFileNameRecord); extendSegment.IsDirectory = true; extendSegment.ReferenceCount = 1; IndexRootRecord extendIndexRoot = (IndexRootRecord)extendSegment.CreateAttributeRecord(AttributeType.IndexRoot, IndexHelper.GetIndexName(AttributeType.FileName)); IndexHelper.InitializeIndexRoot(extendIndexRoot, AttributeType.FileName, CollationRule.Filename, bytesPerIndexRecord, bytesPerCluster); FileNameRecord mftMirrorFileNameRecord = new FileNameRecord(MasterFileTable.RootDirSegmentReference, "$MFTMirr", false, DateTime.Now); int mftMirrorDataLength = 4 * bytesPerFileRecordSegment; int mftMirrorDataClusterCount = (int)Math.Ceiling((double)mftMirrorDataLength / bytesPerCluster); int mftMirrorAllocatedLength = mftMirrorDataClusterCount * bytesPerCluster; mftMirrorFileNameRecord.AllocatedLength = (ulong)mftMirrorAllocatedLength; mftMirrorFileNameRecord.FileSize = (ulong)mftMirrorDataLength; mftMirrorFileNameRecord.FileAttributes = FileAttributes.Hidden | FileAttributes.System; FileRecordSegment mftMirrorSegment = CreateBaseRecordSegment(MasterFileTable.MftMirrorSegmentNumber, (ushort)MasterFileTable.MftMirrorSegmentNumber, mftMirrorFileNameRecord); mftMirrorSegment.ReferenceCount = 1; NonResidentAttributeRecord mftMirrorDataRecord = (NonResidentAttributeRecord)mftMirrorSegment.CreateAttributeRecord(AttributeType.Data, String.Empty, false); mftMirrorDataRecord.AllocatedLength = (ulong)mftMirrorAllocatedLength; mftMirrorDataRecord.FileSize = (ulong)mftMirrorDataLength; mftMirrorDataRecord.ValidDataLength = (ulong)mftMirrorDataLength; long mftMirrorDataStartLCN = upcaseDataStartLCN + upcaseDataClusterCount; mftMirrorDataRecord.DataRunSequence.Add(new DataRun(mftMirrorDataClusterCount, mftMirrorDataStartLCN)); mftMirrorDataRecord.HighestVCN = mftMirrorDataClusterCount - 1; FileNameRecord rootDirFileNameRecord = new FileNameRecord(MasterFileTable.RootDirSegmentReference, ".", true, DateTime.Now); rootDirFileNameRecord.FileAttributes = FileAttributes.System | FileAttributes.Hidden | FileAttributes.FileNameIndexPresent; FileRecordSegment rootDirSegment = CreateBaseRecordSegment(MasterFileTable.RootDirSegmentNumber, (ushort)MasterFileTable.RootDirSegmentNumber, rootDirFileNameRecord); rootDirSegment.IsDirectory = true; rootDirSegment.ReferenceCount = 1; IndexRecord rootDirIndexRecord = new IndexRecord(); rootDirIndexRecord.RecordVBN = 0; // Note that we add the index entries according to collation rules rootDirIndexRecord.IndexEntries.Add(new IndexEntry(attributeDefinitionSegment.SegmentReference, attributeDefinitionFileNameRecord.GetBytes())); rootDirIndexRecord.IndexEntries.Add(new IndexEntry(badClustersSegment.SegmentReference, badClustersFileNameRecord.GetBytes())); rootDirIndexRecord.IndexEntries.Add(new IndexEntry(volumeBitmapSegment.SegmentReference, volumeBitmapFileNameRecord.GetBytes())); rootDirIndexRecord.IndexEntries.Add(new IndexEntry(bootSegment.SegmentReference, bootFileNameRecord.GetBytes())); rootDirIndexRecord.IndexEntries.Add(new IndexEntry(extendSegment.SegmentReference, extendFileNameRecord.GetBytes())); rootDirIndexRecord.IndexEntries.Add(new IndexEntry(logFileSegment.SegmentReference, logFileNameRecord.GetBytes())); rootDirIndexRecord.IndexEntries.Add(new IndexEntry(mftSegment.SegmentReference, mftFileNameRecord.GetBytes())); rootDirIndexRecord.IndexEntries.Add(new IndexEntry(mftMirrorSegment.SegmentReference, mftMirrorFileNameRecord.GetBytes())); rootDirIndexRecord.IndexEntries.Add(new IndexEntry(secureSegment.SegmentReference, secureFileNameRecord.GetBytes())); rootDirIndexRecord.IndexEntries.Add(new IndexEntry(upcaseSegment.SegmentReference, upcaseFileNameRecord.GetBytes())); rootDirIndexRecord.IndexEntries.Add(new IndexEntry(volumeSegment.SegmentReference, volumeFileNameRecord.GetBytes())); rootDirIndexRecord.IndexEntries.Add(new IndexEntry(rootDirSegment.SegmentReference, rootDirFileNameRecord.GetBytes())); long rootDirIndexRecordStartLCN = mftMirrorDataStartLCN + mftMirrorDataClusterCount; int rootDirIndexRecordClusterCount = (int)Math.Ceiling((double)bytesPerIndexRecord / bytesPerCluster); int rootDirIndexRecordAllocatedLength = rootDirIndexRecordClusterCount * bytesPerCluster; string rootDirIndexName = IndexHelper.GetIndexName(AttributeType.FileName); IndexRootRecord rootDirIndexRoot = (IndexRootRecord)rootDirSegment.CreateAttributeRecord(AttributeType.IndexRoot, rootDirIndexName); IndexHelper.InitializeIndexRoot(rootDirIndexRoot, AttributeType.FileName, CollationRule.Filename, bytesPerIndexRecord, bytesPerCluster); rootDirIndexRoot.IsParentNode = true; IndexEntry rootEntry = new IndexEntry(); rootEntry.ParentNodeForm = true; rootEntry.SubnodeVBN = 0; rootDirIndexRoot.IndexEntries.Add(rootEntry); IndexAllocationRecord rootDirIndexAllocation = (IndexAllocationRecord)rootDirSegment.CreateAttributeRecord(AttributeType.IndexAllocation, rootDirIndexName, false); rootDirIndexAllocation.AllocatedLength = (uint)rootDirIndexRecordAllocatedLength; rootDirIndexAllocation.FileSize = (uint)bytesPerIndexRecord; rootDirIndexAllocation.ValidDataLength = (uint)bytesPerIndexRecord; rootDirIndexAllocation.DataRunSequence.Add(new DataRun(rootDirIndexRecordClusterCount, rootDirIndexRecordStartLCN)); rootDirIndexAllocation.HighestVCN = rootDirIndexRecordClusterCount - 1; ResidentAttributeRecord rootDirBitmap = (ResidentAttributeRecord)rootDirSegment.CreateAttributeRecord(AttributeType.Bitmap, rootDirIndexName); rootDirBitmap.Data = new byte[BitmapData.ExtendGranularity]; BitmapData.SetBit(rootDirBitmap.Data, 0); long numberOfClustersInUse = rootDirIndexRecordStartLCN + rootDirIndexRecordClusterCount; long volumeBitmapStartSector = volumeBitmapStartLCN * sectorsPerCluster; WriteVolumeBitmap(volume, volumeBitmapStartSector, volumeClusterCount, numberOfClustersInUse); long mftBitmapStartSector = mftBitmapStartLCN * sectorsPerCluster; WriteMftBitmap(volume, mftBitmapStartSector, numberOfMftRecords, mftBitmapLength); // Write MFT data byte[] mftData = new byte[mftDataLength]; long mftDataStartSector = mftDataStartLCN * sectorsPerCluster; WriteFileRecordSegment(mftData, mftSegment, bytesPerFileRecordSegment, minorNTFSVersion); WriteFileRecordSegment(mftData, mftMirrorSegment, bytesPerFileRecordSegment, minorNTFSVersion); WriteFileRecordSegment(mftData, logFileSegment, bytesPerFileRecordSegment, minorNTFSVersion); WriteFileRecordSegment(mftData, volumeSegment, bytesPerFileRecordSegment, minorNTFSVersion); WriteFileRecordSegment(mftData, attributeDefinitionSegment, bytesPerFileRecordSegment, minorNTFSVersion); WriteFileRecordSegment(mftData, rootDirSegment, bytesPerFileRecordSegment, minorNTFSVersion); WriteFileRecordSegment(mftData, volumeBitmapSegment, bytesPerFileRecordSegment, minorNTFSVersion); WriteFileRecordSegment(mftData, bootSegment, bytesPerFileRecordSegment, minorNTFSVersion); WriteFileRecordSegment(mftData, badClustersSegment, bytesPerFileRecordSegment, minorNTFSVersion); WriteFileRecordSegment(mftData, secureSegment, bytesPerFileRecordSegment, minorNTFSVersion); WriteFileRecordSegment(mftData, upcaseSegment, bytesPerFileRecordSegment, minorNTFSVersion); WriteFileRecordSegment(mftData, extendSegment, bytesPerFileRecordSegment, minorNTFSVersion); for (long segmentNumber = MasterFileTable.ExtendSegmentNumber + 1; segmentNumber < MasterFileTable.FirstReservedSegmentNumber; segmentNumber++) { FileRecordSegment systemSegment = CreateSystemReservedSegment(segmentNumber); WriteFileRecordSegment(mftData, systemSegment, bytesPerFileRecordSegment, minorNTFSVersion); } volume.WriteSectors(mftDataStartSector, mftData); long upcaseDataStartSector = upcaseDataStartLCN * sectorsPerCluster; WriteUpCaseFile(volume, upcaseDataStartSector); long rootDirIndexRecordStartSector = rootDirIndexRecordStartLCN * sectorsPerCluster; WriteIndexRecord(volume, rootDirIndexRecordStartSector, rootDirIndexRecord, bytesPerIndexRecord); // Write MFT mirror data byte[] mftMirrorData = new byte[mftMirrorDataLength]; long mftMirrorDataStartSector = mftMirrorDataStartLCN * sectorsPerCluster; WriteFileRecordSegment(mftMirrorData, mftSegment, bytesPerFileRecordSegment, minorNTFSVersion); WriteFileRecordSegment(mftMirrorData, mftMirrorSegment, bytesPerFileRecordSegment, minorNTFSVersion); WriteFileRecordSegment(mftMirrorData, logFileSegment, bytesPerFileRecordSegment, minorNTFSVersion); WriteFileRecordSegment(mftMirrorData, volumeSegment, bytesPerFileRecordSegment, minorNTFSVersion); volume.WriteSectors(mftMirrorDataStartSector, mftMirrorData); NTFSBootRecord bootRecord = CreateNTFSBootRecord(volumeClusterCount, sectorsPerCluster, volume.BytesPerSector, bytesPerFileRecordSegment, bytesPerIndexRecord, mftDataStartLCN, mftMirrorDataStartLCN); volume.WriteSectors(0, bootRecord.GetBytes()); volume.WriteSectors(volume.TotalSectors - 1, bootRecord.GetBytes()); return(new NTFSVolume(volume)); }
public FileNameAttributeRecord(byte[] buffer, int offset) : base(buffer, offset) { Record = new FileNameRecord(this.Data, 0); }
public bool ContainsFileName(string fileName) { byte[] key = FileNameRecord.GetIndexKeyBytes(fileName); return(FindEntry(key) != null); }
private static FileRecordSegment CreateBaseRecordSegment(long segmentNumber, ushort sequenceNumber, FileNameRecord fileNameRecord) { FileRecordSegment baseRecordSegment = new FileRecordSegment(segmentNumber, sequenceNumber); baseRecordSegment.IsInUse = true; baseRecordSegment.UpdateSequenceNumber = 1; StandardInformationRecord standardInformation = (StandardInformationRecord)baseRecordSegment.CreateAttributeRecord(AttributeType.StandardInformation, String.Empty); standardInformation.CreationTime = fileNameRecord.CreationTime; standardInformation.ModificationTime = fileNameRecord.ModificationTime; standardInformation.MftModificationTime = fileNameRecord.MftModificationTime; standardInformation.LastAccessTime = fileNameRecord.LastAccessTime; standardInformation.FileAttributes = fileNameRecord.FileAttributes; FileNameAttributeRecord fileNameAttribute = (FileNameAttributeRecord)baseRecordSegment.CreateAttributeRecord(AttributeType.FileName, String.Empty); fileNameAttribute.IsIndexed = true; fileNameAttribute.Record = fileNameRecord; return(baseRecordSegment); }
public bool UpdateFileNameRecord(FileNameRecord fileNameRecord) { byte[] key = fileNameRecord.GetBytes(); if (!m_rootRecord.IsParentNode) { int index = CollationHelper.FindIndexInLeafNode(m_rootRecord.IndexEntries, key, m_rootRecord.CollationRule); if (index >= 0) { m_rootRecord.IndexEntries[index].Key = key; m_volume.UpdateFileRecord(m_fileRecord); return(true); } } else { IndexRecord indexRecord = null; bool isParentNode = true; List <IndexEntry> entries = m_rootRecord.IndexEntries; int index; while (isParentNode) { index = CollationHelper.FindIndexInParentNode(entries, key, m_rootRecord.CollationRule); IndexEntry entry = entries[index]; if (!entry.IsLastEntry && CollationHelper.Compare(entry.Key, key, m_rootRecord.CollationRule) == 0) { entries[index].Key = key; if (indexRecord == null) { m_volume.UpdateFileRecord(m_fileRecord); } else { long recordIndex = ConvertToRecordIndex(indexRecord.RecordVBN); WriteIndexRecord(recordIndex, indexRecord); } return(true); } else { long subnodeVBN = entry.SubnodeVBN; indexRecord = ReadIndexRecord(subnodeVBN); isParentNode = indexRecord.IsParentNode; entries = indexRecord.IndexEntries; } } index = CollationHelper.FindIndexInLeafNode(entries, key, m_rootRecord.CollationRule); if (index >= 0) { entries[index].Key = key; if (indexRecord == null) { m_volume.UpdateFileRecord(m_fileRecord); } else { long recordIndex = ConvertToRecordIndex(indexRecord.RecordVBN); WriteIndexRecord(recordIndex, indexRecord); } return(true); } } return(false); }