/// <summary> /// Конструктор /// </summary> /// <param name="drive">Имя логического диска в формате C:</param> public NTFS(string drive) { drive = "\\\\.\\" + drive; // Создаем файл для чтения с диска Drive = HD_API.CreateFile( drive, HD_API.GENERIC_READ, HD_API.FILE_SHARE_READ | HD_API.FILE_SHARE_WRITE, IntPtr.Zero, HD_API.OPEN_EXISTING, 0, IntPtr.Zero ); BPB = new BPB(Drive); // считываем блок параметров БИОС MFT = GetFirstMFT(); // считываем первую запись МФТ }
/// <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); }
/// <summary> /// Конструктор /// </summary> /// <param name="mft">Запись МФТ для отображения</param> public DisplayMFT(MFT mft) { this.mft = mft; }