public static StandardInformation InitializeNewFile(File file, FileAttributeFlags flags) { DateTime now = DateTime.UtcNow; NtfsStream siStream = file.CreateStream(AttributeType.StandardInformation, null); StandardInformation si = new StandardInformation(); si.CreationTime = now; si.ModificationTime = now; si.MftChangedTime = now; si.LastAccessTime = now; si.FileAttributes = flags; siStream.SetContent(si); return si; }
public File InitializeNew(INtfsContext context, long firstBitmapCluster, ulong numBitmapClusters, long firstRecordsCluster, ulong numRecordsClusters) { BiosParameterBlock bpb = context.BiosParameterBlock; FileRecord fileRec = new FileRecord(bpb.BytesPerSector, bpb.MftRecordSize, (uint)MftIndex); fileRec.Flags = FileRecordFlags.InUse; fileRec.SequenceNumber = 1; _recordCache[MftIndex] = fileRec; _self = new File(context, fileRec); StandardInformation.InitializeNewFile(_self, FileAttributeFlags.Hidden | FileAttributeFlags.System); NtfsStream recordsStream = _self.CreateStream(AttributeType.Data, null, firstRecordsCluster, numRecordsClusters, (uint)bpb.BytesPerCluster); _recordStream = recordsStream.Open(FileAccess.ReadWrite); Wipe(_recordStream); NtfsStream bitmapStream = _self.CreateStream(AttributeType.Bitmap, null, firstBitmapCluster, numBitmapClusters, (uint)bpb.BytesPerCluster); using (Stream s = bitmapStream.Open(FileAccess.ReadWrite)) { Wipe(s); s.SetLength(8); _bitmap = new Bitmap(s, long.MaxValue); } _recordLength = context.BiosParameterBlock.MftRecordSize; _bytesPerSector = context.BiosParameterBlock.BytesPerSector; _bitmap.MarkPresentRange(0, 1); // Write the MFT's own record to itself byte[] buffer = new byte[_recordLength]; fileRec.ToBytes(buffer, 0); _recordStream.Position = 0; _recordStream.Write(buffer, 0, _recordLength); _recordStream.Flush(); return(_self); }
private Directory CreateSystemDirectory(long mftIndex) { DateTime now = DateTime.UtcNow; BiosParameterBlock bpb = _context.BiosParameterBlock; FileRecord fileRec = _context.Mft.AllocateRecord((uint)mftIndex, FileRecordFlags.None); fileRec.Flags = FileRecordFlags.InUse | FileRecordFlags.IsDirectory; fileRec.SequenceNumber = (ushort)mftIndex; Directory dir = new Directory(_context, fileRec); StandardInformation.InitializeNewFile(dir, FileAttributeFlags.Hidden | FileAttributeFlags.System); dir.CreateIndex("$I30", AttributeType.FileName, AttributeCollationRule.Filename); dir.UpdateRecordInMft(); return(dir); }
private void VerifyDirectories() { foreach (FileRecord fr in _context.Mft.Records) { if (fr.BaseFile.Value != 0) { continue; } File f = new File(_context, fr); foreach (NtfsStream stream in f.AllStreams) { if (stream.AttributeType == AttributeType.IndexRoot && stream.Name == "$I30") { IndexView <FileNameRecord, FileRecordReference> dir = new IndexView <FileNameRecord, FileRecordReference>(f.GetIndex("$I30")); foreach (KeyValuePair <FileNameRecord, FileRecordReference> entry in dir.Entries) { FileRecord refFile = _context.Mft.GetRecord(entry.Value); // Make sure each referenced file actually exists... if (refFile == null) { ReportError("Directory {0} references non-existent file {1}", f, entry.Key); } File referencedFile = new File(_context, refFile); StandardInformation si = referencedFile.StandardInformation; if (si.CreationTime != entry.Key.CreationTime || si.MftChangedTime != entry.Key.MftChangedTime || si.ModificationTime != entry.Key.ModificationTime) { ReportInfo("Directory entry {0} in {1} is out of date", entry.Key, f); } } } } } }
internal static File CreateNew(INtfsContext context, FileRecordFlags flags) { DateTime now = DateTime.UtcNow; File newFile = context.AllocateFile(flags); StandardInformation.InitializeNewFile(newFile, FileAttributeFlags.Archive | FileRecord.ConvertFlags(flags)); if (context.ObjectIds != null) { Guid newId = CreateNewGuid(context); NtfsStream stream = newFile.CreateStream(AttributeType.ObjectId, null); ObjectId objId = new ObjectId(); objId.Id = newId; stream.SetContent(objId); context.ObjectIds.Add(newId, newFile.MftReference, newId, Guid.Empty, Guid.Empty); } newFile.CreateAttribute(AttributeType.Data, AttributeFlags.None); newFile.UpdateRecordInMft(); return(newFile); }
public void UpdateRecordInMft() { if (MftRecordIsDirty) { if (NtfsTransaction.Current != null) { NtfsStream stream = GetStream(AttributeType.StandardInformation, null); StandardInformation si = stream.GetContent <StandardInformation>(); si.MftChangedTime = NtfsTransaction.Current.Timestamp; stream.SetContent(si); } bool fixesApplied = true; while (fixesApplied) { fixesApplied = false; for (int i = 0; i < _records.Count; ++i) { FileRecord record = _records[i]; bool fixedAttribute = true; while (record.Size > _mft.RecordSize && fixedAttribute) { fixedAttribute = false; if (!fixedAttribute && !record.IsMftRecord) { foreach (AttributeRecord attr in record.Attributes) { if (!attr.IsNonResident && !_context.AttributeDefinitions.MustBeResident(attr.AttributeType)) { MakeAttributeNonResident( new AttributeReference(record.Reference, attr.AttributeId), (int)attr.DataLength); fixedAttribute = true; break; } } } if (!fixedAttribute) { foreach (AttributeRecord attr in record.Attributes) { if (attr.AttributeType == AttributeType.IndexRoot && ShrinkIndexRoot(attr.Name)) { fixedAttribute = true; break; } } } if (!fixedAttribute) { if (record.Attributes.Count == 1) { fixedAttribute = SplitAttribute(record); } else { if (_records.Count == 1) { CreateAttributeList(); } fixedAttribute = ExpelAttribute(record); } } fixesApplied |= fixedAttribute; } } } MftRecordIsDirty = false; foreach (FileRecord record in _records) { _mft.WriteRecord(record); } } }