private List <IndexHeaderDir> IndexElements(byte[] sector, int offset, Attribute attr) { List <IndexHeaderDir> indexes = new List <IndexHeaderDir>(); var fileIndexes = new List <IndexHeader>(); int bodyOffset = attr.ResidentAttr.ValueOffset; // смещение до тела аттрибута IndexRoot indexRoot = new IndexRoot(); // заголовок INDEX_ROOT for (int i = 0; i < 4; i++) { indexRoot.Type += (uint)sector[offset + bodyOffset + i] << (i * 8); } for (int i = 0; i < 4; i++) { indexRoot.CollarationRule += (uint)sector[offset + bodyOffset + i + 0x04] << (i * 8); } for (int i = 0; i < 4; i++) { indexRoot.IndexBlockSize += (uint)sector[offset + bodyOffset + i + 0x08] << (i * 8); } indexRoot.ClustersPerIndexBlock += sector[offset + bodyOffset + 0x0C]; indexRoot.Reserved = new byte[3]; for (int i = 0; i < 3; i++) { indexRoot.Reserved[i] = sector[offset + bodyOffset + 0x0D + i]; } IndexBlockSize = indexRoot.IndexBlockSize; IndexHeader indexHeader = new IndexHeader(); // Заголовок индексной записи int indexHeaderOffset = 0x10 + offset + bodyOffset; for (int i = 0; i < 4; i++) { indexHeader.EntriesOffset += (uint)sector[indexHeaderOffset + i + 0x00] << (i * 8); } for (int i = 0; i < 4; i++) { indexHeader.IndexLength += (uint)sector[indexHeaderOffset + i + 0x04] << (i * 8); } for (int i = 0; i < 4; i++) { indexHeader.AllocatedSize += (uint)sector[indexHeaderOffset + i + 0x08] << (i * 8); } for (int i = 0; i < 4; i++) { indexHeader.Flags += (uint)sector[indexHeaderOffset + i + 0x0C] << (i * 8); } ulong firstIndexElement = 0x10 + indexHeader.EntriesOffset + (ulong)bodyOffset + (ulong)offset; ulong current = firstIndexElement; fileIndexes.Add(indexHeader); //считывание индексных элементов IndexHeaderDir ind; do { ind = new IndexHeaderDir(); for (int i = 0; i < 6; i++) { ind.IndexedFile += (ulong)sector[current + 0x00 + (ulong)i] << (i * 8); } for (int i = 0; i < 2; i++) { ind.Length += (ushort)(sector[current + 0x08 + (ulong)i] << (i * 8)); } for (int i = 0; i < 2; i++) { ind.KeyLength += (ushort)(sector[current + 0x0A + (ulong)i] << (i * 8)); } for (int i = 0; i < 4; i++) { ind.Flags += sector[current + 0x0C + (ulong)i] << (i * 8); } if ((ind.Flags & 2) == 2) { break; } ind.FileName = new byte[ind.KeyLength]; for (int i = 0; i < ind.KeyLength; i++) { ind.FileName[i] = sector[current + 0x10 + (ulong)i]; } string fn = ""; if (ind.KeyLength > 0) { int length = ind.FileName[0x40]; for (int g = 0; g < length * 2; g += 2) { fn += (char)(ind.FileName[0x42 + g] + (ind.FileName[0x42 + g + 1] << 8)); } } ind.FileNameString = fn; if (ind.Flags != 2) { indexes.Add(ind); } current += ind.Length; // пока не встретили элемент с флагом 2 (последний) } while (ind.Flags != 2); return(indexes); }
public List <IndexHeaderDir> IndexAllocationElements(MFTHandle mft, Attribute attr) { if (attr.Type != AttrDef.AT_INDEX_ALLOCATION) { throw new ArgumentException("Incorrect type of attribute"); } var bpb = DiskInfo.BPB; int bytePerCluster = bpb.BytePerSec * bpb.SectorPerCluster; // список индексных элементов List <IndexHeaderDir> indexes = new List <IndexHeaderDir>(); // перебор всех отрезков нерезидентного аттрибута for (int i = 0; i < attr.NotResidentAttr.Clusters.Count; i++) { // текущий кластер int curClus = (int)attr.NotResidentAttr.Clusters[i].Start; // количество кластеров в отрезке int clusters = (int)(attr.NotResidentAttr.Clusters[i].End - attr.NotResidentAttr.Clusters[i].Start); byte[] run = new byte[clusters * (uint)bytePerCluster]; List <byte> list = new List <byte>(); for (int j = 0; j < clusters; j++) { list.AddRange(DiskInfo.ReadCluster(curClus)); curClus++; } run = list.ToArray(); int count = (int)(attr.NotResidentAttr.DataSize / mft.IndexBlockSize); for (int k = 0; k < count; k++) { int offset = (int)(0 + IndexBlockSize * k); // читаем заголовка INDEX_ALLOCATION IndexAllocation ia = new IndexAllocation(); ia.Signature = new byte[4]; for (int j = 0; j < 4; j++) { ia.Signature[j] = run[offset + j]; } for (int j = 0; j < 2; j++) { ia.UsaOffset += (ushort)(run[offset + 0x04 + j] << (j * 8)); } for (int j = 0; j < 2; j++) { ia.UsaCount += (ushort)(run[offset + 0x06 + j] << (j * 8)); } for (int j = 0; j < 8; j++) { ia.Lsn += (ulong)run[offset + 0x08 + j] << (j * 8); } for (int j = 0; j < 8; j++) { ia.IndexBlockVCN += (ulong)run[offset + 0x10 + j] << (j * 8); } // читаем заголовка индексной записи IndexHeader ih = new IndexHeader(); offset += 0x18; for (int j = 0; j < 4; j++) { ih.EntriesOffset += (uint)run[offset + j + 0x00] << (j * 8); } for (int j = 0; j < 4; j++) { ih.IndexLength += (uint)run[offset + j + 0x04] << (j * 8); } for (int j = 0; j < 4; j++) { ih.AllocatedSize += (uint)run[offset + j + 0x08] << (j * 8); } for (int j = 0; j < 4; j++) { ih.Flags += (uint)run[offset + j + 0x0C] << (j * 8); } offset += (int)ih.EntriesOffset; // чтение индексных элемент IndexHeaderDir ind; do { ind = new IndexHeaderDir(); for (int j = 0; j < 6; j++) { ind.IndexedFile += (ulong)run[(uint)offset + 0x00 + (ulong)j] << (j * 8); } for (int j = 0; j < 2; j++) { ind.Length += (ushort)(run[(uint)offset + 0x08 + (ulong)j] << (j * 8)); } for (int j = 0; j < 2; j++) { ind.KeyLength += (ushort)(run[(uint)offset + 0x0A + (ulong)j] << (j * 8)); } for (int j = 0; j < 4; j++) { ind.Flags += run[(uint)offset + 0x0C + (ulong)j] << (j * 8); } if ((ind.Flags & 2) == 2) { break; } ind.FileName = new byte[ind.KeyLength]; for (int j = 0; j < ind.KeyLength; j++) { ind.FileName[j] = run[(uint)offset + 0x10 + (ulong)j]; } string fn = ""; if (ind.KeyLength > 0) { int length = ind.FileName[0x40]; for (int g = 0; g < length * 2; g += 2) { fn += (char)(ind.FileName[0x42 + g] + (ind.FileName[0x42 + g + 1] << 8)); } } ind.FileNameString = fn; if (ind.Flags != 2) { indexes.Add(ind); } offset += ind.Length; } while (ind.Flags != 2); // пока не встретим элемент с флагом 2 (т.е. последний) } } return(indexes); }