internal FileNameAttribute(INtfsContext context, AttributeRecord record) : base(context, record) { byte[] content = Utilities.ReadAll(Content); _fnr = new FileNameRecord(); _fnr.ReadFrom(content, 0); }
public void UpdateFileName(string profile, string path, string fileName) { var cacheKey = GetCacheKey(profile, path); var profileCache = GetProfileCache(profile); string existingFileName; if (profileCache.TryGetValue(cacheKey, out existingFileName) && existingFileName == fileName) { return; } profileCache[cacheKey] = fileName; var profilePart = _imageProfileService.GetImageProfileByName(profile); // profile might not exist in the db if its a dynamic profile if (profilePart != null) { var fileNameRecord = profilePart.FileNames.FirstOrDefault(f => f.Path == path); if (fileNameRecord == null) { fileNameRecord = new FileNameRecord { Path = path, ImageProfilePartRecord = profilePart.Record }; profilePart.FileNames.Add(fileNameRecord); } fileNameRecord.FileName = fileName; } }
public static void CreateVolumeWithPendingFileCreation(string path, long size, int bytesPerCluster, string volumeLabel, string fileName, byte[] fileData) { VirtualHardDisk disk = VirtualHardDisk.CreateFixedDisk(path, size); disk.ExclusiveLock(); Partition partition = NTFSFormatTests.CreatePrimaryPartition(disk); NTFSVolume volume = NTFSVolumeCreator.Format(partition, bytesPerCluster, volumeLabel); long segmentNumber = MasterFileTable.FirstUserSegmentNumber; FileNameRecord fileNameRecord = new FileNameRecord(MasterFileTable.RootDirSegmentReference, fileName, false, DateTime.Now); FileRecordSegment fileRecordSegment = CreateFileRecordSegment(segmentNumber, fileNameRecord, fileData); ulong dataStreamOffset = (ulong)(segmentNumber * volume.BytesPerFileRecordSegment); byte[] redoData = fileRecordSegment.GetBytes(volume.BytesPerFileRecordSegment, volume.MinorVersion, false); MftSegmentReference mftFileReference = new MftSegmentReference(0, 1); AttributeRecord mftDataRecord = volume.GetFileRecord(mftFileReference).GetAttributeRecord(AttributeType.Data, String.Empty); AttributeRecord mftBitmapRecord = volume.GetFileRecord(mftFileReference).GetAttributeRecord(AttributeType.Bitmap, String.Empty); uint transactionID = volume.LogClient.AllocateTransactionID(); volume.LogClient.WriteLogRecord(mftFileReference, mftDataRecord, dataStreamOffset, volume.BytesPerFileRecordSegment, NTFSLogOperation.InitializeFileRecordSegment, redoData, NTFSLogOperation.Noop, new byte[0], transactionID); long bitmapVCN = segmentNumber / (volume.BytesPerCluster * 8); int bitOffsetInCluster = (int)(segmentNumber % (volume.BytesPerCluster * 8)); BitmapRange bitmapRange = new BitmapRange((uint)bitOffsetInCluster, 1); ulong bitmapStreamOffset = (ulong)(bitmapVCN * volume.BytesPerCluster); volume.LogClient.WriteLogRecord(mftFileReference, mftBitmapRecord, bitmapStreamOffset, volume.BytesPerCluster, NTFSLogOperation.SetBitsInNonResidentBitMap, bitmapRange.GetBytes(), NTFSLogOperation.Noop, new byte[0], transactionID); FileRecord parentDirectoryRecord = volume.GetFileRecord(MasterFileTable.RootDirSegmentReference); IndexData parentDirectoryIndex = new IndexData(volume, parentDirectoryRecord, AttributeType.FileName); byte[] fileNameRecordBytes = fileNameRecord.GetBytes(); long leafRecordVBN = 0; IndexRecord leafRecord = parentDirectoryIndex.ReadIndexRecord(leafRecordVBN); ulong indexAllocationOffset = (ulong)parentDirectoryIndex.ConvertToDataOffset(leafRecordVBN); int insertIndex = CollationHelper.FindIndexForSortedInsert(leafRecord.IndexEntries, fileNameRecordBytes, CollationRule.Filename); int insertOffset = leafRecord.GetEntryOffset(volume.BytesPerIndexRecord, insertIndex); AttributeRecord rootDirIndexAllocation = volume.GetFileRecord(MasterFileTable.RootDirSegmentReference).GetAttributeRecord(AttributeType.IndexAllocation, IndexHelper.GetIndexName(AttributeType.FileName)); IndexEntry indexEntry = new IndexEntry(fileRecordSegment.SegmentReference, fileNameRecord.GetBytes()); volume.LogClient.WriteLogRecord(MasterFileTable.RootDirSegmentReference, rootDirIndexAllocation, indexAllocationOffset, volume.BytesPerIndexRecord, 0, insertOffset, NTFSLogOperation.AddIndexEntryToAllocationBuffer, indexEntry.GetBytes(), NTFSLogOperation.Noop, new byte[0], transactionID, false); volume.LogClient.WriteForgetTransactionRecord(transactionID, true); disk.ReleaseLock(); }
/// <summary> /// This test checks that attributes are deep cloned when assembled from FileRecordSegment list and sliced into FileRecordSegment list. /// </summary> public static void AttributeCloneTest() { byte minorNTFSVersion = 1; int bytesPerFileRecordSegment = 1024; FileRecordSegment baseSegment = new FileRecordSegment(30, 1); FileRecordSegment segment2 = new FileRecordSegment(31, 1, baseSegment.SegmentReference); FileNameRecord fileNameRecord = new FileNameRecord(NTFSVolume.RootDirSegmentReference, "john.txt", false, DateTime.Now); FileNameAttributeRecord fileNameAttribute = new FileNameAttributeRecord(String.Empty); fileNameAttribute.Record = fileNameRecord; NonResidentAttributeRecord dataRecord = new NonResidentAttributeRecord(AttributeType.Data, String.Empty); baseSegment.ImmediateAttributes.Add(fileNameAttribute); baseSegment.ImmediateAttributes.Add(dataRecord); dataRecord.DataRunSequence.Add(new DataRun(5, 0)); byte[] segmentBytesBefore = baseSegment.GetBytes(bytesPerFileRecordSegment, minorNTFSVersion, false); List <FileRecordSegment> segments = new List <FileRecordSegment>(); segments.Add(baseSegment); segments.Add(segment2); FileRecord fileRecord = new FileRecord(segments); ((NonResidentAttributeRecord)fileRecord.DataRecord).DataRunSequence[0].RunLength = 8; fileRecord.FileNameRecord.ParentDirectory = new MftSegmentReference(8, 8); fileRecord.FileNameRecord.FileName = "d"; byte[] segmentBytesAfter = baseSegment.GetBytes(bytesPerFileRecordSegment, minorNTFSVersion, false); if (!ByteUtils.AreByteArraysEqual(segmentBytesBefore, segmentBytesAfter)) { throw new Exception("Test failed"); } fileRecord.UpdateSegments(1024, 1); byte[] segmentBytesBefore2 = fileRecord.Segments[0].GetBytes(bytesPerFileRecordSegment, minorNTFSVersion, false); ((NonResidentAttributeRecord)fileRecord.DataRecord).DataRunSequence[0].RunLength = 10; fileRecord.FileNameRecord.FileName = "x"; byte[] segmentBytesAfter2 = fileRecord.Segments[0].GetBytes(bytesPerFileRecordSegment, minorNTFSVersion, false); if (!ByteUtils.AreByteArraysEqual(segmentBytesBefore2, segmentBytesAfter2)) { throw new Exception("Test failed"); } }
private static FileRecordSegment CreateFileRecordSegment(long segmentNumber, FileNameRecord fileNameRecord, byte[] fileData) { fileNameRecord.AllocatedLength = (uint)fileData.Length; fileNameRecord.FileSize = (uint)fileData.Length; FileRecordSegment fileRecordSegment = new FileRecordSegment(segmentNumber, 1); fileRecordSegment.IsInUse = true; fileRecordSegment.ReferenceCount = 1; StandardInformationRecord standardInformation = (StandardInformationRecord)fileRecordSegment.CreateAttributeRecord(AttributeType.StandardInformation, String.Empty); standardInformation.CreationTime = fileNameRecord.CreationTime; standardInformation.ModificationTime = fileNameRecord.ModificationTime; standardInformation.MftModificationTime = fileNameRecord.MftModificationTime; standardInformation.LastAccessTime = fileNameRecord.LastAccessTime; FileNameAttributeRecord fileNameAttribute = (FileNameAttributeRecord)fileRecordSegment.CreateAttributeRecord(AttributeType.FileName, String.Empty); fileNameAttribute.IsIndexed = true; fileNameAttribute.Record = fileNameRecord; ResidentAttributeRecord dataRecord = (ResidentAttributeRecord)fileRecordSegment.CreateAttributeRecord(AttributeType.Data, String.Empty); dataRecord.Data = fileData; return(fileRecordSegment); }
internal void FreshenFileName(FileNameRecord fileName, bool updateMftRecord) { // // Freshen the record from the definitive info in the other attributes // StandardInformation si = StandardInformation; NtfsAttribute anonDataAttr = GetAttribute(AttributeType.Data, null); fileName.CreationTime = si.CreationTime; fileName.ModificationTime = si.ModificationTime; fileName.MftChangedTime = si.MftChangedTime; fileName.LastAccessTime = si.LastAccessTime; fileName.Flags = si.FileAttributes; if (_dirty && NtfsTransaction.Current != null) { fileName.MftChangedTime = NtfsTransaction.Current.Timestamp; } // Directories don't have directory flag set in StandardInformation, so set from MFT record if ((_records[0].Flags & FileRecordFlags.IsDirectory) != 0) { fileName.Flags |= FileAttributeFlags.Directory; } if (anonDataAttr != null) { fileName.RealSize = (ulong)anonDataAttr.PrimaryRecord.DataLength; fileName.AllocatedSize = (ulong)anonDataAttr.PrimaryRecord.AllocatedLength; } if (updateMftRecord) { foreach (NtfsStream stream in GetStreams(AttributeType.FileName, null)) { FileNameRecord fnr = stream.GetContent<FileNameRecord>(); if (fnr.Equals(fileName)) { fnr = new FileNameRecord(fileName); fnr.Flags &= ~FileAttributeFlags.ReparsePoint; stream.SetContent(fnr); } } } }
internal static string EntryAsString(IndexEntry entry, string fileName, string indexName) { IByteArraySerializable keyValue = null; IByteArraySerializable dataValue = null; // Try to guess the type of data in the key and data fields from the filename and index name if (indexName == "$I30") { keyValue = new FileNameRecord(); dataValue = new FileRecordReference(); } else if (fileName == "$ObjId" && indexName == "$O") { keyValue = new ObjectIds.IndexKey(); dataValue = new ObjectIdRecord(); } else if (fileName == "$Reparse" && indexName == "$R") { keyValue = new ReparsePoints.Key(); dataValue = new ReparsePoints.Data(); } else if (fileName == "$Quota") { if (indexName == "$O") { keyValue = new Quotas.OwnerKey(); dataValue = new Quotas.OwnerRecord(); } else if (indexName == "$Q") { keyValue = new Quotas.OwnerRecord(); dataValue = new Quotas.QuotaRecord(); } } else if (fileName == "$Secure") { if (indexName == "$SII") { keyValue = new SecurityDescriptors.IdIndexKey(); dataValue = new SecurityDescriptors.IdIndexData(); } else if (indexName == "$SDH") { keyValue = new SecurityDescriptors.HashIndexKey(); dataValue = new SecurityDescriptors.IdIndexData(); } } try { if (keyValue != null && dataValue != null) { keyValue.ReadFrom(entry.KeyBuffer, 0); dataValue.ReadFrom(entry.DataBuffer, 0); return "{" + keyValue + "-->" + dataValue + "}"; } } catch { return "{Parsing-Error}"; } return "{Unknown-Index-Type}"; }
public DirectoryEntry(Directory directory, FileRecordReference fileReference, FileNameRecord fileDetails) { _directory = directory; _fileReference = fileReference; _fileDetails = fileDetails; }
public FileNameAttributeRecord(byte[] buffer, int offset) : base(buffer, offset) { Record = new FileNameRecord(this.Data, 0); }