} // The offset to the value from the start of the attribute record, in bytes. /* * /// <summary> * /// Indexed flag 1 bit + padding which contains an empty byte = total 2 bytes * /// indexed flag ? * /// </summary> * public byte[] Reserved { get; set; }/*= new byte[2]; */ public static AttributeResidentHeader ReadHeader(byte[] data, int offset = 0) { if (data.Length - offset < 6 || offset < 0) { throw new Exception("Error!\n"); } AttributeResidentHeader resident = new AttributeResidentHeader(); resident.ValueLength = BitConverter.ToUInt32(data, offset); resident.ValueOffset = BitConverter.ToUInt16(data, offset + 4); /*resident.Reserved = new byte[2]; * resident.Reserved[2] = data[offset + 7];*/ return(resident); }
public static AttributeRecord ReadSingleAttribute(byte[] data, int maxLength, int offset = 0) { Debug.Assert(data.Length - offset >= maxLength); Debug.Assert(0 <= offset && offset <= data.Length); AttributeTypeCode TypeCode = GetTypeCode(data, offset); if (TypeCode == AttributeTypeCode.EndOfAttributes) { AttributeRecord tmpAR = new AttributeGeneric(); tmpAR.ReadARHeader(data, offset); return(tmpAR); } AttributeRecord attRecord; switch (TypeCode) { case AttributeTypeCode.STANDARD_INFORMATION: attRecord = new StandardInformation(); break; case AttributeTypeCode.ATTRIBUTE_LIST: attRecord = new AttributeList(); break; case AttributeTypeCode.FILE_NAME: attRecord = new FileName(); break; case AttributeTypeCode.OBJECT_ID: attRecord = new ObjectId(); break; // To complicated to quickly be implemented. Maybe one day. lol // case AttributeTypeCode.SECURITY_DESCRIPTOR: // attRecord = new SecurityDescriptor(); // break; case AttributeTypeCode.VOLUME_NAME: attRecord = new VolumeName(); break; case AttributeTypeCode.VOLUME_INFORMATION: attRecord = new VolumeInformation(); break; case AttributeTypeCode.DATA: attRecord = new Data(); break; case AttributeTypeCode.INDEX_ROOT: attRecord = new IndexRoot(); break; // INDEX_ALLOCATION is stored as non resident and this project deals only with resident files // case AttributeTypeCode.INDEX_ALLOCATION: // attRecord = new IndexAllocation(); // break; case AttributeTypeCode.BITMAP: attRecord = new Bitmap(); break; case AttributeTypeCode.EA_INFORMATION: attRecord = new ExtenedAttributeInformation(); break; case AttributeTypeCode.EA: attRecord = new ExtenedAttributes(); break; // PROPERTY_SET needs a pre NTFS 3.0 volume. This is probably obsolete! // case AttributeTypeCode.PROPERTY_SET: // attRecord = new PropertSet(); // break; case AttributeTypeCode.LOGGED_UTILITY_STREAM: attRecord = new LoggedUtilityStream(); break; default: // ?? could be a problem attRecord = new AttributeGeneric(); break; } attRecord.ReadARHeader(data, offset); if (attRecord.FormCode == ResidentFileFlag.Resident) { attRecord.ResidentHeader = AttributeResidentHeader.ReadHeader(data, offset + 16); int residentBodyOffset = offset + attRecord.ResidentHeader.ValueOffset; int length = offset + attRecord.RecordLength - residentBodyOffset; attRecord.ReadAttributeResident(data, length, residentBodyOffset); } else { throw new Exception("Could not read and process resident flag!\n"); } return(attRecord); }