Exemple #1
0
        public static IndexAllocationChunk ParseBody(INTFSInfo 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.BytesPrSector, (ushort)ntfsInfo.BytesPrSector, 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.HasFlag(MFTIndexEntryFlags.LastEntry))
                {
                    break;
                }

                entries.Add(entry);

                pointer += entry.Size;
            }

            res.Entries = entries.ToArray();

            return(res);
        }
        internal override void ParseAttributeResidentBody(byte[] data, int maxLength, int offset)
        {
            base.ParseAttributeResidentBody(data, maxLength, offset);

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

            IndexType             = (AttributeType)BitConverter.ToUInt32(data, offset);
            CollationRule         = BitConverter.ToUInt32(data, offset + 4);
            IndexAllocationSize   = BitConverter.ToUInt32(data, offset + 8);
            ClustersPrIndexRecord = data[offset + 12];

            OffsetToFirstIndex   = BitConverter.ToUInt32(data, offset + 16);
            SizeOfIndexTotal     = BitConverter.ToUInt32(data, offset + 20);
            SizeOfIndexAllocated = BitConverter.ToUInt32(data, offset + 24);
            IndexFlags           = (MFTIndexRootFlags)data[offset + 28];

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

            // Parse entries
            int pointer = offset + 32;

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

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

                entries.Add(entry);

                pointer += entry.Size;
            }

            Entries = entries;
        }