}                                                       // 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);
        }
Пример #2
0
        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);
        }