예제 #1
0
        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;
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
                            }
                        }
                    }
                }
            }
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
                }
            }
        }