예제 #1
0
        internal FileName(ResidentHeader header, byte[] attrBytes, string attrName)
        {
            // Headers
            Name        = (ATTR_TYPE)header.commonHeader.ATTRType;
            NameString  = attrName;
            NonResident = header.commonHeader.NonResident;
            AttributeId = header.commonHeader.Id;

            // FILE_NAME Attribute
            ParentSequenceNumber = (BitConverter.ToUInt16(attrBytes, 0x06));
            ParentRecordNumber   = (BitConverter.ToUInt64(attrBytes, 0x00) & 0x0000FFFFFFFFFFFF);
            BornTime             = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x08));
            ChangedTime          = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x10));
            ModifiedTime         = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x18));
            AccessedTime         = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x20));
            AllocatedSize        = BitConverter.ToUInt64(attrBytes, 0x28);
            RealSize             = BitConverter.ToUInt64(attrBytes, 0x30);
            Flags      = BitConverter.ToUInt32(attrBytes, 0x38);
            ER         = BitConverter.ToUInt32(attrBytes, 0x3C);
            NameLength = attrBytes[0x40];
            Namespace  = Convert.ToInt32(attrBytes[0x41]);

            // Get FileName
            Filename = Encoding.Unicode.GetString(attrBytes, 0x42, NameLength * 2).TrimEnd('\0');
        }
예제 #2
0
        internal ObjectId(ResidentHeader header, byte[] attrBytes, string attrName)
        {
            Name        = (ATTR_TYPE)header.commonHeader.ATTRType;
            NameString  = attrName;
            NonResident = header.commonHeader.NonResident;
            AttributeId = header.commonHeader.Id;


            ObjectIdGuid = new Guid(NativeMethods.GetSubArray(attrBytes, 0x00, 0x10));

            if (!(attrBytes.Length < 0x20))
            {
                BirthVolumeId = new Guid(NativeMethods.GetSubArray(attrBytes, 0x10, 0x10));

                if (!(attrBytes.Length < 0x30))
                {
                    BirthObjectId = new Guid(NativeMethods.GetSubArray(attrBytes, 0x20, 0x10));

                    if (attrBytes.Length == 0x40)
                    {
                        BirthDomainId = new Guid(NativeMethods.GetSubArray(attrBytes, 0x30, 0x10));
                    }
                }
            }
        }
예제 #3
0
        internal FileName(ResidentHeader header, byte[] attrBytes, string attrName)
        {
            // Headers
            Name = (ATTR_TYPE)header.commonHeader.ATTRType;
            NameString = attrName;
            NonResident = header.commonHeader.NonResident;
            AttributeId = header.commonHeader.Id;

            // FILE_NAME Attribute
            ParentSequenceNumber = (BitConverter.ToUInt16(attrBytes, 0x06));
            ParentRecordNumber = (BitConverter.ToUInt64(attrBytes, 0x00) & 0x0000FFFFFFFFFFFF);
            BornTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x08));
            ChangedTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x10));
            ModifiedTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x18));
            AccessedTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x20));
            AllocatedSize = BitConverter.ToUInt64(attrBytes, 0x28);
            RealSize = BitConverter.ToUInt64(attrBytes, 0x30);
            Flags = BitConverter.ToUInt32(attrBytes, 0x38);
            ER = BitConverter.ToUInt32(attrBytes, 0x3C);
            NameLength = attrBytes[0x40];
            Namespace = Convert.ToInt32(attrBytes[0x41]);

            // Get FileName
            Filename = Encoding.Unicode.GetString(attrBytes, 0x42, NameLength * 2).TrimEnd('\0');
        }
예제 #4
0
 internal Data(ResidentHeader header, byte[] attrBytes, string attrName)
 {
     Name        = (ATTR_TYPE)header.commonHeader.ATTRType;
     NameString  = attrName;
     NonResident = header.commonHeader.NonResident;
     AttributeId = header.commonHeader.Id;
     RawData     = NativeMethods.GetSubArray(attrBytes, 0x00, (uint)attrBytes.Length);
 }
예제 #5
0
 internal Data(ResidentHeader header, byte[] attrBytes, string attrName)
 {
     Name = (ATTR_TYPE)header.commonHeader.ATTRType;
     NameString = attrName;
     NonResident = header.commonHeader.NonResident;
     AttributeId = header.commonHeader.Id;
     RawData = NativeMethods.GetSubArray(attrBytes, 0x00, (uint)attrBytes.Length);
 }
예제 #6
0
        internal VolumeName(ResidentHeader header, byte[] attrBytes, string attrName)
        {
            Name = (ATTR_TYPE)header.commonHeader.ATTRType;
            NameString = attrName;
            NonResident = header.commonHeader.NonResident;
            AttributeId = header.commonHeader.Id;

            VolumeNameString = Encoding.Unicode.GetString(attrBytes, 0x00, (int)header.AttrSize);
        }
예제 #7
0
        internal VolumeName(ResidentHeader header, byte[] attrBytes, string attrName)
        {
            Name        = (ATTR_TYPE)header.commonHeader.ATTRType;
            NameString  = attrName;
            NonResident = header.commonHeader.NonResident;
            AttributeId = header.commonHeader.Id;

            VolumeNameString = Encoding.Unicode.GetString(attrBytes, 0x00, (int)header.AttrSize);
        }
        internal VolumeInformation(ResidentHeader header, byte[] attrBytes, string attrName)
        {
            Name = (ATTR_TYPE)header.commonHeader.ATTRType;
            NameString = attrName;
            NonResident = header.commonHeader.NonResident;
            AttributeId = header.commonHeader.Id;

            Version = new Version(attrBytes[0x08], attrBytes[0x09]);
            Flags = (ATTR_VOLINFO)BitConverter.ToInt16(attrBytes, 0x0A);
        }
        internal VolumeInformation(ResidentHeader header, byte[] attrBytes, string attrName)
        {
            Name        = (ATTR_TYPE)header.commonHeader.ATTRType;
            NameString  = attrName;
            NonResident = header.commonHeader.NonResident;
            AttributeId = header.commonHeader.Id;

            Version = new Version(attrBytes[0x08], attrBytes[0x09]);
            Flags   = (ATTR_VOLINFO)BitConverter.ToInt16(attrBytes, 0x0A);
        }
예제 #10
0
        internal AttributeList(ResidentHeader header, byte[] attrBytes, string attrName)
        {
            Name        = (Attr.ATTR_TYPE)header.commonHeader.ATTRType;
            NameString  = attrName;
            NonResident = header.commonHeader.NonResident;
            AttributeId = header.commonHeader.Id;

            #region AttributeReference

            int            i       = 0;
            List <AttrRef> refList = new List <AttrRef>();

            while (i < attrBytes.Length)
            {
                AttrRef attrRef = new AttrRef(NativeMethods.GetSubArray(attrBytes, (uint)i, (uint)BitConverter.ToUInt16(attrBytes, i + 0x04)));
                refList.Add(attrRef);
                i += attrRef.RecordLength;
            }
            AttributeReference = refList.ToArray();

            #endregion AttributeReference
        }
예제 #11
0
        internal AttributeList(ResidentHeader header, byte[] attrBytes, string attrName)
        {
            Name = (Attr.ATTR_TYPE)header.commonHeader.ATTRType;
            NameString = attrName;
            NonResident = header.commonHeader.NonResident;
            AttributeId = header.commonHeader.Id;

            #region AttributeReference

            int i = 0;
            List<AttrRef> refList = new List<AttrRef>();

            while (i < attrBytes.Length)
            {
                AttrRef attrRef = new AttrRef(NativeMethods.GetSubArray(attrBytes, (uint)i, (uint)BitConverter.ToUInt16(attrBytes, i + 0x04)));
                refList.Add(attrRef);
                i += attrRef.RecordLength;
            }
            AttributeReference = refList.ToArray();

            #endregion AttributeReference
        }
예제 #12
0
        internal StandardInformation(ResidentHeader header, byte[] attrBytes, string attrName)
        {
            Name        = (ATTR_TYPE)header.commonHeader.ATTRType;
            NameString  = attrName;
            NonResident = header.commonHeader.NonResident;
            AttributeId = header.commonHeader.Id;

            BornTime         = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x00));
            ModifiedTime     = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x08));
            ChangedTime      = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x10));
            AccessedTime     = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x18));
            Permission       = ((ATTR_STDINFO_PERMISSION)BitConverter.ToUInt32(attrBytes, 0x20));
            MaxVersionNumber = BitConverter.ToUInt32(attrBytes, 0x24);
            VersionNumber    = BitConverter.ToUInt32(attrBytes, 0x28);
            ClassId          = BitConverter.ToUInt32(attrBytes, 0x2C);

            if (attrBytes.Length == 0x48)
            {
                OwnerId              = BitConverter.ToUInt32(attrBytes, 0x30);
                SecurityId           = BitConverter.ToUInt32(attrBytes, 0x34);
                QuotaCharged         = BitConverter.ToUInt64(attrBytes, 0x38);
                UpdateSequenceNumber = BitConverter.ToUInt64(attrBytes, 0x40);
            }
        }
예제 #13
0
        internal ObjectId(ResidentHeader header, byte[] attrBytes, string attrName)
        {
            Name = (ATTR_TYPE)header.commonHeader.ATTRType;
            NameString = attrName;
            NonResident = header.commonHeader.NonResident;
            AttributeId = header.commonHeader.Id;

            ObjectIdGuid = new Guid(NativeMethods.GetSubArray(attrBytes, 0x00, 0x10));

            if (!(attrBytes.Length < 0x20))
            {
                BirthVolumeId = new Guid(NativeMethods.GetSubArray(attrBytes, 0x10, 0x10));

                if (!(attrBytes.Length < 0x30))
                {
                    BirthObjectId = new Guid(NativeMethods.GetSubArray(attrBytes, 0x20, 0x10));

                    if(attrBytes.Length == 0x40)
                    {
                        BirthDomainId = new Guid(NativeMethods.GetSubArray(attrBytes, 0x30, 0x10));
                    }
                }
            }
        }
        internal StandardInformation(ResidentHeader header, byte[] attrBytes, string attrName)
        {
            Name = (ATTR_TYPE)header.commonHeader.ATTRType;
            NameString = attrName;
            NonResident = header.commonHeader.NonResident;
            AttributeId = header.commonHeader.Id;

            BornTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x00));
            ModifiedTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x08));
            ChangedTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x10));
            AccessedTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x18));
            Permission = ((ATTR_STDINFO_PERMISSION)BitConverter.ToUInt32(attrBytes, 0x20));
            MaxVersionNumber = BitConverter.ToUInt32(attrBytes, 0x24);
            VersionNumber = BitConverter.ToUInt32(attrBytes, 0x28);
            ClassId = BitConverter.ToUInt32(attrBytes, 0x2C);

            if (attrBytes.Length == 0x48)
            {
                OwnerId = BitConverter.ToUInt32(attrBytes, 0x30);
                SecurityId = BitConverter.ToUInt32(attrBytes, 0x34);
                QuotaCharged = BitConverter.ToUInt64(attrBytes, 0x38);
                UpdateSequenceNumber = BitConverter.ToUInt64(attrBytes, 0x40);
            }
        }
예제 #15
0
        internal static Attr Get(byte[] bytes, string volume)
        {
            #region CommonHeader

            if (bytes.Length == 0)
            {
                return(null);
            }

            // Instantiate a Common Header Object
            CommonHeader commonHeader = new CommonHeader(bytes);

            #endregion CommonHeader

            uint NameLength = (uint)commonHeader.NameLength * 2;

            // Decode Name byte[] into Unicode String
            string attributeName = Encoding.Unicode.GetString(bytes, (int)commonHeader.NameOffset, (int)NameLength);

            // Determine if Attribute is Resident or NonResident
            bool resident = (bytes[8] == 0x00);

            #region ResidentAttribute

            // If Attribute is Resident
            if (resident)
            {
                #region ResidentHeader

                // Instantiate a Resident Header Object
                ResidentHeader residentHeader = new ResidentHeader(NativeMethods.GetSubArray(bytes, COMMONHEADERSIZE, RESIDENTHEADERSIZE), commonHeader);

                #endregion ResidentHeader

                #region AttributeBytes

                // Create a byte[] representing the attribute itself
                int    headerSize     = COMMONHEADERSIZE + RESIDENTHEADERSIZE + (int)NameLength;
                byte[] attributeBytes = NativeMethods.GetSubArray(bytes, (uint)headerSize, commonHeader.TotalSize - (uint)headerSize);

                #endregion AttributeBytes

                #region ATTRSwitch

                switch (residentHeader.commonHeader.ATTRType)
                {
                case (Int32)Attr.ATTR_TYPE.STANDARD_INFORMATION:
                    return(new StandardInformation(residentHeader, attributeBytes, attributeName));

                case (Int32)Attr.ATTR_TYPE.ATTRIBUTE_LIST:
                    return(new AttributeList(residentHeader, attributeBytes, attributeName));

                case (Int32)Attr.ATTR_TYPE.FILE_NAME:
                    return(new FileName(residentHeader, attributeBytes, attributeName));

                case (Int32)Attr.ATTR_TYPE.OBJECT_ID:
                    return(new ObjectId(residentHeader, attributeBytes, attributeName));

                case (Int32)Attr.ATTR_TYPE.VOLUME_NAME:
                    return(new VolumeName(residentHeader, attributeBytes, attributeName));

                case (Int32)Attr.ATTR_TYPE.VOLUME_INFORMATION:
                    return(new VolumeInformation(residentHeader, attributeBytes, attributeName));

                case (Int32)Attr.ATTR_TYPE.DATA:
                    return(new Data(residentHeader, attributeBytes, attributeName));

                case (Int32)Attr.ATTR_TYPE.INDEX_ROOT:
                    return(new IndexRoot(residentHeader, attributeBytes, attributeName));

                default:
                    return(null);
                }

                #endregion ATTRSwitch
            }

            #endregion ResidentAttribute

            #region NonResidentAttribute
            // Else Attribute is Non-Resident
            else
            {
                #region NonResidentHeader

                // Instantiate a Resident Header Object
                NonResidentHeader nonresidentHeader = new NonResidentHeader(NativeMethods.GetSubArray(bytes, COMMONHEADERSIZE, NONRESIDENTHEADERSIZE), commonHeader);

                #endregion NonResidentHeader

                #region DataRun

                int headerSize = 0;

                if (commonHeader.NameOffset != 0)
                {
                    headerSize = commonHeader.NameOffset + (int)NameLength + ((int)NameLength % 8);
                }
                else
                {
                    headerSize = COMMONHEADERSIZE + NONRESIDENTHEADERSIZE;
                }

                return(new NonResident(nonresidentHeader, NativeMethods.GetSubArray(bytes, (uint)headerSize, commonHeader.TotalSize - (uint)headerSize), attributeName));

                #endregion DataRun
            }
            #endregion NonResidentAttribute
        }
예제 #16
0
        internal IndexRoot(ResidentHeader header, byte[] attrBytes, string attrName)
        {
            #region ResidentHeader

            // Get ResidentHeader (includes Common Header)
            Name = (ATTR_TYPE)header.commonHeader.ATTRType;
            NameString = attrName;
            NonResident = header.commonHeader.NonResident;
            AttributeId = header.commonHeader.Id;

            #endregion ResidentHeader

            #region IndexRoot

            // IndexRoot
            AttributeType = (ATTR_TYPE)BitConverter.ToUInt32(attrBytes, 0x00);
            CollationSortingRule = BitConverter.ToUInt32(attrBytes, 0x04);
            IndexSize = BitConverter.ToUInt32(attrBytes, 0x08);
            ClustersPerIndexRecord = attrBytes[0x0C];

            #endregion IndexRoot

            #region IndexHeader

            // IndexHeader
            StartOffset = (BitConverter.ToUInt32(attrBytes, 0x10) + 0x10);  // Add 0x10 bytes to start offset to account for its offset
            TotalSize = BitConverter.ToUInt32(attrBytes, 0x14);
            AllocatedSize = BitConverter.ToUInt32(attrBytes, 0x18);
            Flags = ((INDEX_ROOT_FLAGS)BitConverter.ToUInt32(attrBytes, 0x1C));

            #endregion IndexHeader

            #region IndexEntryArray

            if(TotalSize > StartOffset){
                // IndexEntry[]
                byte[] EntryBytes = NativeMethods.GetSubArray(attrBytes, StartOffset, TotalSize - StartOffset);

                // Iterate through IndexEntry object
                int indexEntryOffset = 0;

                if (AttributeType == ATTR_TYPE.FILE_NAME)
                {
                    // Instantiate empty IndexEntry List
                    List<IndexEntry> entryList = new List<IndexEntry>();

                    while (indexEntryOffset < (EntryBytes.Length - 0x10))
                    {
                        // Creat byte array representing IndexEntry Object
                        int indexEntrySizeOffset = indexEntryOffset + 0x08;

                        // Instantiate an IndexEntry Object
                        IndexEntry indexEntry = new IndexEntry(NativeMethods.GetSubArray(EntryBytes, (uint)indexEntryOffset, (uint)BitConverter.ToUInt16(EntryBytes, indexEntrySizeOffset)));

                        // Add IndexEntry Object to FileName List
                        entryList.Add(indexEntry);

                        // Increment indexEntryOffset
                        indexEntryOffset += indexEntry.Size;
                    }

                    Entries = entryList.ToArray();
                }
            }
            #endregion IndexEntryArray
        }
        internal static Attr Get(byte[] bytes, string volume)
        {
            #region CommonHeader

            if (bytes.Length == 0)
            {
                return null;
            }

            // Instantiate a Common Header Object
            CommonHeader commonHeader = new CommonHeader(bytes);

            #endregion CommonHeader

            uint NameLength = (uint)commonHeader.NameLength * 2;

            // Decode Name byte[] into Unicode String
            string attributeName = Encoding.Unicode.GetString(bytes, (int)commonHeader.NameOffset, (int)NameLength);

            // Determine if Attribute is Resident or NonResident
            bool resident = (bytes[8] == 0x00);

            #region ResidentAttribute

            // If Attribute is Resident
            if (resident)
            {
                #region ResidentHeader

                // Instantiate a Resident Header Object
                ResidentHeader residentHeader = new ResidentHeader(NativeMethods.GetSubArray(bytes, COMMONHEADERSIZE, RESIDENTHEADERSIZE), commonHeader);

                #endregion ResidentHeader

                #region AttributeBytes

                // Create a byte[] representing the attribute itself
                int headerSize = COMMONHEADERSIZE + RESIDENTHEADERSIZE + (int)NameLength;
                byte[] attributeBytes = NativeMethods.GetSubArray(bytes, (uint)headerSize, commonHeader.TotalSize - (uint)headerSize);

                #endregion AttributeBytes

                #region ATTRSwitch

                switch (residentHeader.commonHeader.ATTRType)
                {
                    case (Int32)Attr.ATTR_TYPE.STANDARD_INFORMATION:
                        return new StandardInformation(residentHeader, attributeBytes, attributeName);

                    case (Int32)Attr.ATTR_TYPE.ATTRIBUTE_LIST:
                        return new AttributeList(residentHeader, attributeBytes, attributeName);

                    case (Int32)Attr.ATTR_TYPE.FILE_NAME:
                        return new FileName(residentHeader, attributeBytes, attributeName);

                    case (Int32)Attr.ATTR_TYPE.OBJECT_ID:
                        return new ObjectId(residentHeader, attributeBytes, attributeName);

                    case (Int32)Attr.ATTR_TYPE.VOLUME_NAME:
                        return new VolumeName(residentHeader, attributeBytes, attributeName);

                    case (Int32)Attr.ATTR_TYPE.VOLUME_INFORMATION:
                        return new VolumeInformation(residentHeader, attributeBytes, attributeName);

                    case (Int32)Attr.ATTR_TYPE.DATA:
                        return new Data(residentHeader, attributeBytes, attributeName);

                    case (Int32)Attr.ATTR_TYPE.INDEX_ROOT:
                        return new IndexRoot(residentHeader, attributeBytes, attributeName);

                    default:
                        return null;
                }

                #endregion ATTRSwitch
            }

            #endregion ResidentAttribute

            #region NonResidentAttribute
            // Else Attribute is Non-Resident
            else
            {
                #region NonResidentHeader

                // Instantiate a Resident Header Object
                NonResidentHeader nonresidentHeader = new NonResidentHeader(NativeMethods.GetSubArray(bytes, COMMONHEADERSIZE, NONRESIDENTHEADERSIZE), commonHeader);

                #endregion NonResidentHeader

                #region DataRun

                int headerSize = 0;

                if (commonHeader.NameOffset != 0)
                {
                    headerSize = commonHeader.NameOffset + (int)NameLength + ((int)NameLength % 8);
                }
                else
                {
                    headerSize = COMMONHEADERSIZE + NONRESIDENTHEADERSIZE;
                }

                return new NonResident(nonresidentHeader, NativeMethods.GetSubArray(bytes, (uint)headerSize, commonHeader.TotalSize - (uint)headerSize), attributeName);

                #endregion DataRun
            }
            #endregion NonResidentAttribute
        }
예제 #18
0
        internal IndexRoot(ResidentHeader header, byte[] attrBytes, string attrName)
        {
            #region ResidentHeader

            // Get ResidentHeader (includes Common Header)
            Name        = (ATTR_TYPE)header.commonHeader.ATTRType;
            NameString  = attrName;
            NonResident = header.commonHeader.NonResident;
            AttributeId = header.commonHeader.Id;

            #endregion ResidentHeader

            #region IndexRoot

            // IndexRoot
            AttributeType          = (ATTR_TYPE)BitConverter.ToUInt32(attrBytes, 0x00);
            CollationSortingRule   = BitConverter.ToUInt32(attrBytes, 0x04);
            IndexSize              = BitConverter.ToUInt32(attrBytes, 0x08);
            ClustersPerIndexRecord = attrBytes[0x0C];

            #endregion IndexRoot

            #region IndexHeader

            // IndexHeader
            StartOffset   = (BitConverter.ToUInt32(attrBytes, 0x10) + 0x10); // Add 0x10 bytes to start offset to account for its offset
            TotalSize     = BitConverter.ToUInt32(attrBytes, 0x14);
            AllocatedSize = BitConverter.ToUInt32(attrBytes, 0x18);
            Flags         = ((INDEX_ROOT_FLAGS)BitConverter.ToUInt32(attrBytes, 0x1C));

            #endregion IndexHeader

            #region IndexEntryArray

            if (TotalSize > StartOffset)
            {
                // IndexEntry[]
                byte[] EntryBytes = NativeMethods.GetSubArray(attrBytes, StartOffset, TotalSize - StartOffset);


                // Iterate through IndexEntry object
                int indexEntryOffset = 0;

                if (AttributeType == ATTR_TYPE.FILE_NAME)
                {
                    // Instantiate empty IndexEntry List
                    List <IndexEntry> entryList = new List <IndexEntry>();

                    while (indexEntryOffset < (EntryBytes.Length - 0x10))
                    {
                        // Creat byte array representing IndexEntry Object
                        int indexEntrySizeOffset = indexEntryOffset + 0x08;

                        // Instantiate an IndexEntry Object
                        IndexEntry indexEntry = new IndexEntry(NativeMethods.GetSubArray(EntryBytes, (uint)indexEntryOffset, (uint)BitConverter.ToUInt16(EntryBytes, indexEntrySizeOffset)));

                        // Add IndexEntry Object to FileName List
                        entryList.Add(indexEntry);

                        // Increment indexEntryOffset
                        indexEntryOffset += indexEntry.Size;
                    }

                    Entries = entryList.ToArray();
                }
            }
            #endregion IndexEntryArray
        }