internal IndexAllocation(NonResident header, string volume)
        {
            // Headers
            Name = (ATTR_TYPE)header.commonHeader.ATTRType;
            NameString = header.NameString;
            NonResident = header.commonHeader.NonResident;
            AttributeId = header.commonHeader.Id;

            // Get IndexAllocation Bytes
            byte[] bytes = header.GetBytes(volume);

            // Instantiate empty IndexEntry List
            List<IndexEntry> indexEntryList = new List<IndexEntry>();

            // Iterate through IndexBlocks (4096 bytes in size)
            for (int offset = 0; offset < bytes.Length; offset += 4096)
            {
                // Detemine size of Update Sequence
                ushort usOffset = BitConverter.ToUInt16(bytes, offset + 0x04);
                ushort usSize = BitConverter.ToUInt16(bytes, offset + 0x06);
                int indexBlockSize = usOffset + (usSize * 2);

                if (indexBlockSize == 0)
                {
                    break;
                }

                IndexBlock.ApplyFixup(ref bytes, offset);

                // Instantiate IndexBlock Object (Header)
                IndexBlock indexBlock = new IndexBlock(NativeMethods.GetSubArray(bytes, (uint)offset, (uint)indexBlockSize));

                // Create byte array for IndexEntry object
                // 0x18 represents the offset of the EntryOffset value, so it must be added on
                byte[] indexEntryBytes = NativeMethods.GetSubArray(bytes, (uint)offset + indexBlock.EntryOffset + 0x18, indexBlock.TotalEntrySize);

                int entryOffset = 0;

                do
                {
                    // Instantiate an IndexEntry Object
                    IndexEntry indexEntry = new IndexEntry(NativeMethods.GetSubArray(indexEntryBytes, (uint)entryOffset, BitConverter.ToUInt16(indexEntryBytes, entryOffset + 0x08)));
                    entryOffset += indexEntry.Size;

                    // Check if entry is the last in the Entry array
                    if (indexEntry.Flags == 0x02 || indexEntry.Flags == 0x03)
                    {
                        break;
                    }

                    // Add IndexEntry Object to list
                    indexEntryList.Add(indexEntry);

                }while(entryOffset < indexEntryBytes.Length);
            }
            Entries = indexEntryList.ToArray();
        }
        public static IndexEntry[] GetInstances(string path)
        {
            string[] paths = path.TrimEnd('\\').Split('\\');

            // Determine Volume Name
            string volume = @"\\.\" + paths[0];

            // Test volume path
            NativeMethods.getVolumeName(ref volume);

            int index = -1;

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

            for (int i = 0; i < paths.Length; i++)
            {
                if (index == -1)
                {
                    index = 5;
                }
                else
                {
                    bool match = false;

                    foreach (IndexEntry entry in indexEntryList)
                    {

                        if (entry.Entry.Filename.ToUpper() == paths[i].ToUpper())
                        {
                            index = (int)entry.RecordNumber;
                            match = true;
                        }
                    }
                    if (!(match))
                    {
                        throw new Exception("Path " + path + " not found.");
                    }
                }

                FileRecord record = new FileRecord(FileRecord.GetRecordBytes(volume, index), volume);

                indexEntryList.Clear();

                if (record.Directory)
                {
                    foreach (Attr attr in record.Attribute)
                    {
                        if (attr.Name == Attr.ATTR_TYPE.INDEX_ROOT)
                        {
                            try
                            {
                                foreach (IndexEntry entry in (attr as IndexRoot).Entries)
                                {
                                    if (entry.Entry.Namespace != 0x02)
                                    {
                                        StringBuilder sb = new StringBuilder();
                                        sb.Append(path.TrimEnd('\\'));
                                        sb.Append("\\");
                                        sb.Append(entry.Filename);
                                        entry.FullName = sb.ToString();
                                        indexEntryList.Add(entry);
                                    }
                                }
                            }
                            catch
                            {
                                return null;
                            }
                        }
                        else if (attr.Name == Attr.ATTR_TYPE.INDEX_ALLOCATION)
                        {
                            // Get INDEX_ALLOCATION bytes
                            IndexAllocation IA = new IndexAllocation(attr as NonResident, volume);

                            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

                            foreach (IndexEntry entry in IA.Entries)
                            {
                                if (entry.Entry.Namespace != 0x02)
                                {
                                    StringBuilder sb = new StringBuilder();
                                    sb.Append(path.TrimEnd('\\'));
                                    sb.Append("\\");
                                    sb.Append(entry.Filename);
                                    entry.FullName = sb.ToString();
                                    indexEntryList.Add(entry);
                                }
                            }
                        }
                    }
                }
                else
                {
                    IndexEntry[] indexArray = new IndexEntry[1];
                    indexArray[0] = new IndexEntry(record);
                    return indexArray;
                }
            }

            return indexEntryList.ToArray();
        }
示例#3
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
        }