internal override void ParseAttributeNonResidentBody(INTFSInfo ntfsInfo)
        {
            byte[] data = NtfsUtils.ReadFragments(ntfsInfo, NonResidentHeader.Fragments);

            List <IndexAllocationChunk> indexes = new List <IndexAllocationChunk>();
            List <IndexEntry>           entries = new List <IndexEntry>();

            // Parse
            for (int i = 0; i < NonResidentHeader.Fragments.Length; i++)
            {
                for (int j = 0; j < NonResidentHeader.Fragments[i].Clusters; j++)
                {
                    int offset = (int)((NonResidentHeader.Fragments[i].StartingVCN - NonResidentHeader.Fragments[0].StartingVCN) * ntfsInfo.BytesPrCluster + j * ntfsInfo.BytesPrCluster);

                    if (!IndexAllocationChunk.IsIndexAllocationChunk(data, offset))
                    {
                        continue;
                    }

                    IndexAllocationChunk index = IndexAllocationChunk.ParseBody(ntfsInfo, data, offset);

                    indexes.Add(index);
                    entries.AddRange(index.Entries);
                }
            }

            Indexes = indexes.ToArray();
            Entries = entries.ToArray();
        }
示例#2
0
        internal override void ParseAttributeResidentBody(byte[] data, int maxLength, int offset)
        {
            base.ParseAttributeResidentBody(data, maxLength, offset);

            // Debug.Assert(maxLength >= 48);

            TimeCreated     = NtfsUtils.FromWinFileTime(data, offset);
            TimeModified    = NtfsUtils.FromWinFileTime(data, offset + 8);
            TimeMftModified = NtfsUtils.FromWinFileTime(data, offset + 16);
            TimeAccessed    = NtfsUtils.FromWinFileTime(data, offset + 24);
            DosPermissions  = (FileAttributes)BitConverter.ToInt32(data, offset + 32);

            MaxmiumVersions = BitConverter.ToUInt32(data, offset + 36);
            VersionNumber   = BitConverter.ToUInt32(data, offset + 40);
            ClassId         = BitConverter.ToUInt32(data, offset + 44);

            // The below fields are for version 3.0+
            if (NonResidentFlag == ResidentFlag.Resident && ResidentHeader.ContentLength >= 72)
            {
                // Debug.Assert(maxLength >= 72);

                OwnerId      = BitConverter.ToUInt32(data, offset + 48);
                SecurityId   = BitConverter.ToUInt32(data, offset + 52);
                QuotaCharged = BitConverter.ToUInt64(data, offset + 56);
                USN          = BitConverter.ToUInt64(data, offset + 64);
            }
        }
示例#3
0
        internal static NtfsFileEntry CreateEntry(NTFSWrapper ntfsWrapper, uint fileId, AttributeFileName fileName = null)
        {
            if (fileName == null)
            {
                // Dig up a preferred name
                FileRecord tmpRecord = ntfsWrapper.ReadMFTRecord(fileId);
                fileName = NtfsUtils.GetPreferredDisplayName(tmpRecord);
            }

            NtfsFileEntry entry = ntfsWrapper.FileCache.Get(fileId, fileName.FileName.GetHashCode());

            if (entry != null)
            {
                Debug.WriteLine("Got from cache: " + fileId + ":" + fileName.Id);
                return(entry);
            }

            // Create it
            FileRecord record = ntfsWrapper.ReadMFTRecord(fileId);

            if (record.Flags.HasFlag(FileEntryFlags.Directory))
            {
                entry = new NtfsDirectory(ntfsWrapper, record, fileName);
            }
            else
            {
                entry = new NtfsFile(ntfsWrapper, record, fileName);
            }

            ntfsWrapper.FileCache.Set(fileId, fileName.Id, entry);

            return(entry);
        }
        internal override void ParseAttributeNonResidentBody(INTFSInfo ntfsInfo)
        {
            base.ParseAttributeNonResidentBody(ntfsInfo);

            // Get all chunks
            byte[] data = NtfsUtils.ReadFragments(ntfsInfo, NonResidentHeader.Fragments);

            // Parse
            Debug.Assert(data.Length >= 8);

            List <ExtendedAttribute> extendedAttributes = new List <ExtendedAttribute>();
            int pointer = 0;

            while (pointer + 8 <= data.Length)       // 8 is the minimum size of an ExtendedAttribute
            {
                if (ExtendedAttribute.GetSize(data, pointer) <= 0)
                {
                    break;
                }

                ExtendedAttribute ea = ExtendedAttribute.ParseData(data, (int)NonResidentHeader.ContentSize, pointer);

                extendedAttributes.Add(ea);

                pointer += ea.Size;
            }

            ExtendedAttributes = extendedAttributes.ToArray();
        }
        public static FileRecord Parse(byte[] data, int offset, ushort bytesPrSector, uint sectors)
        {
            uint length = bytesPrSector * sectors;

            Debug.Assert(data.Length - offset >= length);
            Debug.Assert(length >= 50);
            Debug.Assert(bytesPrSector % 512 == 0 && bytesPrSector > 0);
            Debug.Assert(sectors > 0);

            FileRecord res = new FileRecord();

            Debug.Assert(res != null);

            //if (res == null)
            //{
            //	return null;
            //}


            res.Signature = Encoding.ASCII.GetString(data, offset + 0, 4);
            Debug.Assert(res.Signature == "FILE");

            res.OffsetToUSN            = BitConverter.ToUInt16(data, offset + 4);
            res.USNSizeWords           = BitConverter.ToUInt16(data, offset + 6);
            res.LogFileUSN             = BitConverter.ToUInt64(data, offset + 8);
            res.SequenceNumber         = BitConverter.ToUInt16(data, offset + 16);
            res.HardlinkCount          = BitConverter.ToInt16(data, offset + 18);
            res.OffsetToFirstAttribute = BitConverter.ToUInt16(data, offset + 20);
            res.Flags                     = (FileEntryFlags)BitConverter.ToUInt16(data, offset + 22);
            res.SizeOfFileRecord          = BitConverter.ToUInt32(data, offset + 24);
            res.SizeOfFileRecordAllocated = BitConverter.ToUInt32(data, offset + 28);
            res.BaseFile                  = new FileReference(BitConverter.ToUInt64(data, offset + 32));
            res.NextFreeAttributeId       = BitConverter.ToUInt16(data, offset + 40);
            // Two unused bytes here
            res.MFTNumber = BitConverter.ToUInt32(data, offset + 44);

            res.USNNumber = new byte[2];
            Array.Copy(data, offset + res.OffsetToUSN, res.USNNumber, 0, 2);

            Debug.Assert(data.Length - offset >= res.OffsetToUSN + 2 + res.USNSizeWords * 2);

            res.USNData = new byte[res.USNSizeWords * 2 - 2];
            Array.Copy(data, offset + res.OffsetToUSN + 2, res.USNData, 0, res.USNData.Length);

            res.FileReference = new FileReference(res.MFTNumber, res.SequenceNumber);

            // Apply the USN Path
            NtfsUtils.ApplyUSNPatch(data, offset, sectors, bytesPrSector, res.USNNumber, res.USNData);

            res._attributes         = new List <Attribute>();
            res._externalAttributes = new List <Attribute>();

            // Parse attributes
            res.ParseAttributes(data, res.SizeOfFileRecord - res.OffsetToFirstAttribute, offset + res.OffsetToFirstAttribute);

            return(res);
        }
示例#6
0
        public static IndexAllocationChunk ParseBody(Ntfs ntfsInfo, byte[] data, int offset)
        {
            // Debug.Assert(data.Length >= 36);

            IndexAllocationChunk res = new IndexAllocationChunk();

            // Parse
            res.Signature = Encoding.ASCII.GetString(data, offset + 0, 4);

            // Debug.Assert(res.Signature == "INDX");

            res.OffsetToUSN          = BitConverter.ToUInt16(data, offset + 4);
            res.USNSizeWords         = BitConverter.ToUInt16(data, offset + 6);
            res.LogFileUSN           = BitConverter.ToUInt64(data, offset + 8);
            res.VCNInIndexAllocation = BitConverter.ToUInt64(data, offset + 16);
            res.OffsetToFirstIndex   = BitConverter.ToUInt32(data, offset + 24);
            res.SizeOfIndexTotal     = BitConverter.ToUInt32(data, offset + 28);
            res.SizeOfIndexAllocated = BitConverter.ToUInt32(data, offset + 32);
            res.HasChildren          = data[36];

            // Debug.Assert(data.Length >= offset + res.OffsetToUSN + 2 + res.USNSizeWords * 2);

            res.USNNumber = new byte[2];
            Array.Copy(data, offset + res.OffsetToUSN, res.USNNumber, 0, 2);

            res.USNData = new byte[res.USNSizeWords * 2 - 2];
            Array.Copy(data, offset + res.OffsetToUSN + 2, res.USNData, 0, res.USNData.Length);

            // Patch USN Data
            NtfsUtils.ApplyUSNPatch(data, offset, (res.SizeOfIndexAllocated + 24) / ntfsInfo.BytesPerSector, (ushort)ntfsInfo.BytesPerSector, res.USNNumber, res.USNData);

            // Debug.Assert(offset + res.SizeOfIndexTotal <= data.Length);

            // Parse entries
            List <IndexEntry> entries = new List <IndexEntry>();

            int pointer = offset + (int)(res.OffsetToFirstIndex + 24);       // Offset is relative to 0x18

            while (pointer <= offset + res.SizeOfIndexTotal + 24)
            {
                IndexEntry entry = IndexEntry.ParseData(data, offset + (int)res.SizeOfIndexTotal - pointer + 24, pointer);

                if ((entry.Flags & MFTIndexEntryFlags.LastEntry) != 0)
                {
                    break;
                }

                entries.Add(entry);

                pointer += entry.Size;
            }

            res.Entries = entries;

            return(res);
        }
示例#7
0
        internal override void ParseAttributeNonResidentBody(INTFSInfo ntfsInfo)
        {
            base.ParseAttributeNonResidentBody(ntfsInfo);

            // Get all chunks
            byte[] data = NtfsUtils.ReadFragments(ntfsInfo, NonResidentHeader.Fragments);

            // Parse
            Bitfield = new BitArray(data);
        }
示例#8
0
        internal static NtfsFileEntry CreateEntry(Ntfs ntfs, uint fileId, AttributeFileName fileName = null)
        {
            var record = ntfs.ReadMftRecord(fileId);

            if (fileName == null)
            {
                fileName = NtfsUtils.GetPreferredDisplayName(record);
            }

            if ((record.Flags & FileEntryFlags.Directory) != 0)
            {
                return(new NtfsDirectory(ntfs, record, fileName));
            }
            return(new NtfsFile(ntfs, record, fileName));
        }
示例#9
0
        public string BuildFileName(FileRecord record, string rootName = null)
        {
            // Get filename (and prefer the non-8dot3 variant)
            AttributeFileName fileName = NtfsUtils.GetPreferredDisplayName(record);

            if (fileName == null)
            {
                throw new NullReferenceException("Record has no FileName attribute");
            }

            string path = fileName.FileName;

            if (record.Flags.HasFlag(FileEntryFlags.Directory))
            {
                path += '\\';
            }

            // Continue till we hit SpecialMFTFiles.RootDir
            FileRecord parentRecord;

            do
            {
                // Get parent
                parentRecord = ReadMFTRecord(fileName.ParentDirectory.FileId);

                if (parentRecord == null)
                {
                    throw new NullReferenceException("A parent record was null");
                }

                fileName = NtfsUtils.GetPreferredDisplayName(parentRecord);

                if (fileName == null)
                {
                    throw new NullReferenceException("A parent record had no Filename attribute");
                }

                if (parentRecord.FileReference.FileId == (uint)SpecialMFTFiles.RootDir)
                {
                    path = rootName + '\\' + path;
                    break;
                }
                path = fileName.FileName + '\\' + path;
            }while (true);

            return(path);
        }
示例#10
0
        internal override void ParseAttributeResidentBody(byte[] data, int maxLength, int offset)
        {
            base.ParseAttributeResidentBody(data, maxLength, offset);

            ParentDirectory    = new FileReference(BitConverter.ToUInt64(data, offset));
            CTime              = NtfsUtils.FromWinFileTime(data, offset + 8);
            ATime              = NtfsUtils.FromWinFileTime(data, offset + 16);
            MTime              = NtfsUtils.FromWinFileTime(data, offset + 24);
            RTime              = NtfsUtils.FromWinFileTime(data, offset + 32);
            AllocatedSize      = BitConverter.ToUInt64(data, offset + 40);
            RealSize           = BitConverter.ToUInt64(data, offset + 48);
            FileFlags          = (FileAttributes)BitConverter.ToInt32(data, offset + 56);
            ReservedEAsReparse = BitConverter.ToUInt32(data, offset + 60);
            FilenameLength     = data[offset + 64];
            FilenameNamespace  = (FileNamespace)data[offset + 65];

            Debug.Assert(maxLength >= 66 + FilenameLength * 2);

            FileName = Encoding.Unicode.GetString(data, offset + 66, FilenameLength * 2);
        }
        internal override void ParseAttributeNonResidentBody(RawDisk disk)
        {
            base.ParseAttributeNonResidentBody(disk);

            // Get all chunks
            byte[] data = NtfsUtils.ReadFragments(disk, NonResidentHeader.Fragments);

            // Parse
            List <AttributeListItem> results = new List <AttributeListItem>();

            int pointer     = 0;
            int contentSize = (int)NonResidentHeader.ContentSize;

            while (pointer + 26 <= contentSize)     // 26 is the smallest possible MFTAttributeListItem
            {
                AttributeListItem item = AttributeListItem.ParseListItem(data, data.Length - pointer, pointer);

                if (item.Type == AttributeType.EndOfAttributes)
                {
                    break;
                }

                if (item.Length == 0)
                {
                    break;
                }

                results.Add(item);

                pointer += item.Length;
            }

            Debug.Assert(pointer == contentSize);

            Items = results.ToArray();
        }