/// <summary> /// Считываем индексные элементы из аттрибута INDEX_ROOT /// </summary> /// <param name="sector">Запись МФТ в виде массива байт</param> /// <param name="offset">Смещение до начала аттрибута</param> /// <param name="attr">Аттрибут</param> /// <returns></returns> private List <IndexHeaderDir> IndexElements(byte[] sector, int offset, Attribute attr) { List <IndexHeaderDir> indexes = new List <IndexHeaderDir>(); int bodyOffset = attr.Resident.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; 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; } while (ind.Flags != 2);// пока не встретим элемент с флагом 2 (т.е. последний) return(indexes); }
/// <summary> /// Чтение индексных элементов из аттрибута INDEX_ALLOCATION /// </summary> /// <param name="mft">Запись МФТ, которой принадлежит аттрибут</param> /// <param name="attr">Аттрибут INDEX_ALLOCATION</param> /// <returns></returns> public List <IndexHeaderDir> IndexAllocationElements(MFT mft, Attribute attr) { if (attr.Type != AttributeTypes.AT_INDEX_ALLOCATION) { throw new ArgumentException("Incorrect type of attribute"); } var bpb = NTFS.BPB; int bytePerCluster = bpb.BytePerSec * bpb.SectorPerCluster; List <IndexHeaderDir> indexes = new List <IndexHeaderDir>(); // список индексных элементов for (int i = 0; i < attr.NonResident.Clusters.Count; i++) // перебираем все отрезки нерезидентного аттрибута { int curClus = (int)attr.NonResident.Clusters[i].Start; // текущий кластер int clusters = (int)(attr.NonResident.Clusters[i].End - attr.NonResident.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(NTFS.ReadCluster(curClus)); curClus++; } run = list.ToArray(); int count = (int)(attr.NonResident.DataSize / mft.IndexBlockSize); // количество индексных for (int k = 0; k < count; k++) // перебираем индексные записи { int offset = (int)(0 + IndexBlockSize * k); IndexAllocation ia = new IndexAllocation(); // читаем заголовок INDEX_ALLOCATION 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); }