# -*- coding: utf-8 -*-


from rawdisk.util.rawstruct import RawStruct


class MftAttrHeader(RawStruct):
    """Represents MFT attribute header.

    Attributes:
        type (uint): Attribute type.
        length (uint): Attribute length (including this header).
        non_resident_flag (ubyte): Non-resident flag (0 - resident, \
            1 - otherwise).
        length_of_name (ubyte): If attribute has name, this is name \
        length in bytes.
        offset_to_name (ushort): Offset to attribute's name in bytes.
        attr_name (unicode): Attribuet's name (if it has one).
        flags (ushort): The attribute flags (COMPRESSION_MASK (0x00FF), \
            SPARSE (0x8000), ENCRYPTED (0x4000)).
        identifier (ushort): The unique identifier for this attribute \
        in the file record.

        Resident attribute:
        attr_length (uint): The size of the attribute value, in bytes.
        attr_offset (ushort): The offset to the value from the start of \
        the attribute record, in bytes.
        indexed (ubyte): Indexed flag??

        Non-resident attribute:
        lowest_vcn (ulonglong): The lowest virtual cluster number (VCN) \
        covered by this attribute record.
        highest_vcn (ulonglong): The highest VCN covered by this \
        attribute record.
        data_run_offset (ushort): The offset to the mapping \
        pairs array from the start of the attribute record, in bytes.
        comp_unit_size (ushort): Compression unit size = 2 x clusters. \
        0 implies uncompressed.
        alloc_size (ulonglong): The allocated size of the file, in bytes. \
        This value is an even multiple of the cluster size. \
        This member is not valid if the LowestVcn member is nonzero.
        real_size (ulonglong): The file size (highest byte that can be \
            read plus 1), in bytes. \
        This member is not valid if LowestVcn is nonzero.
        data_size (ulonglong): The valid data length (highest initialized \
            byte plus 1), in bytes. This value is rounded to the nearest \
        cluster boundary. This member is not valid if LowestVcn is nonzero.


    See More:
        | http://ftp.kolibrios.org\
/users/Asper/docs/NTFS/ntfsdoc.html#concept_attribute_header
        | http://msdn.microsoft.com/en-us/library/bb470039(v=vs.85).aspx
    """
    def __init__(self, data):
        RawStruct.__init__(self, data)
        self.type = self.get_uint_le(0)
        self.length = self.get_uint_le(0x4)
        self.non_resident_flag = self.get_ubyte(0x08)   # 0 - resident, 1 - not
        self.length_of_name = self.get_ubyte(0x09)      # Used only for ADS
        self.offset_to_name = self.get_ushort_le(0x0A)     # Used only for ADS

        # (Compressed, Encrypted, Sparse)
        self.flags = self.get_ushort_le(0x0C)
        self.identifier = self.get_ushort_le(0x0E)

        if (self.non_resident_flag):
            # Attribute is Non-Resident
            self.lowest_vcn = self.get_ulonglong_le(0x10)
            self.highest_vcn = self.get_ulonglong_le(0x18)
            self.data_run_offset = self.get_ushort_le(0x20)
            self.comp_unit_size = self.get_ushort_le(0x22)
            # 4 byte 0x00 padding @ 0x24
            self.alloc_size = self.get_ulonglong_le(0x28)
            self.real_size = self.get_ulonglong_le(0x30)
            self.data_size = self.get_ulonglong_le(0x38)

            if (self.length_of_name > 0):
                self.attr_name = self.get_chunk(
                    0x40, 2 * self.length_of_name).decode('utf-16')
                # print self.attr_name.decode('utf-16')
        else:
            # Attribute is Resident
            self.attr_length = self.get_uint_le(0x10)
            self.attr_offset = self.get_ushort_le(0x14)
            self.indexed = self.get_ubyte(0x16)
            if (self.length_of_name > 0):
                self.attr_name = self.get_chunk(
                    0x18, 2 * self.length_of_name).decode('utf-16')
                # print self.attr_name.decode('utf-16')
            # The rest byte is 0x00 padding
            # print "Attr Offset: 0x%x" % (self.attr_offset)

b3a087801458b934d7e7c7daf564f4d4bb869a85
<mask token>


class MftAttrHeader(RawStruct):
    <mask token>
    <mask token>

<mask token>


class MftAttrHeader(RawStruct):
    <mask token>

    def __init__(self, data):
        RawStruct.__init__(self, data)
        self.type = self.get_uint_le(0)
        self.length = self.get_uint_le(4)
        self.non_resident_flag = self.get_ubyte(8)
        self.length_of_name = self.get_ubyte(9)
        self.offset_to_name = self.get_ushort_le(10)
        self.flags = self.get_ushort_le(12)
        self.identifier = self.get_ushort_le(14)
        if self.non_resident_flag:
            self.lowest_vcn = self.get_ulonglong_le(16)
            self.highest_vcn = self.get_ulonglong_le(24)
            self.data_run_offset = self.get_ushort_le(32)
            self.comp_unit_size = self.get_ushort_le(34)
            self.alloc_size = self.get_ulonglong_le(40)
            self.real_size = self.get_ulonglong_le(48)
            self.data_size = self.get_ulonglong_le(56)
            if self.length_of_name > 0:
                self.attr_name = self.get_chunk(64, 2 * self.length_of_name
                    ).decode('utf-16')
        else:
            self.attr_length = self.get_uint_le(16)
            self.attr_offset = self.get_ushort_le(20)
            self.indexed = self.get_ubyte(22)
            if self.length_of_name > 0:
                self.attr_name = self.get_chunk(24, 2 * self.length_of_name
                    ).decode('utf-16')

<mask token>


class MftAttrHeader(RawStruct):
    """Represents MFT attribute header.

    Attributes:
        type (uint): Attribute type.
        length (uint): Attribute length (including this header).
        non_resident_flag (ubyte): Non-resident flag (0 - resident,             1 - otherwise).
        length_of_name (ubyte): If attribute has name, this is name         length in bytes.
        offset_to_name (ushort): Offset to attribute's name in bytes.
        attr_name (unicode): Attribuet's name (if it has one).
        flags (ushort): The attribute flags (COMPRESSION_MASK (0x00FF),             SPARSE (0x8000), ENCRYPTED (0x4000)).
        identifier (ushort): The unique identifier for this attribute         in the file record.

        Resident attribute:
        attr_length (uint): The size of the attribute value, in bytes.
        attr_offset (ushort): The offset to the value from the start of         the attribute record, in bytes.
        indexed (ubyte): Indexed flag??

        Non-resident attribute:
        lowest_vcn (ulonglong): The lowest virtual cluster number (VCN)         covered by this attribute record.
        highest_vcn (ulonglong): The highest VCN covered by this         attribute record.
        data_run_offset (ushort): The offset to the mapping         pairs array from the start of the attribute record, in bytes.
        comp_unit_size (ushort): Compression unit size = 2 x clusters.         0 implies uncompressed.
        alloc_size (ulonglong): The allocated size of the file, in bytes.         This value is an even multiple of the cluster size.         This member is not valid if the LowestVcn member is nonzero.
        real_size (ulonglong): The file size (highest byte that can be             read plus 1), in bytes.         This member is not valid if LowestVcn is nonzero.
        data_size (ulonglong): The valid data length (highest initialized             byte plus 1), in bytes. This value is rounded to the nearest         cluster boundary. This member is not valid if LowestVcn is nonzero.


    See More:
        | http://ftp.kolibrios.org/users/Asper/docs/NTFS/ntfsdoc.html#concept_attribute_header
        | http://msdn.microsoft.com/en-us/library/bb470039(v=vs.85).aspx
    """

    def __init__(self, data):
        RawStruct.__init__(self, data)
        self.type = self.get_uint_le(0)
        self.length = self.get_uint_le(4)
        self.non_resident_flag = self.get_ubyte(8)
        self.length_of_name = self.get_ubyte(9)
        self.offset_to_name = self.get_ushort_le(10)
        self.flags = self.get_ushort_le(12)
        self.identifier = self.get_ushort_le(14)
        if self.non_resident_flag:
            self.lowest_vcn = self.get_ulonglong_le(16)
            self.highest_vcn = self.get_ulonglong_le(24)
            self.data_run_offset = self.get_ushort_le(32)
            self.comp_unit_size = self.get_ushort_le(34)
            self.alloc_size = self.get_ulonglong_le(40)
            self.real_size = self.get_ulonglong_le(48)
            self.data_size = self.get_ulonglong_le(56)
            if self.length_of_name > 0:
                self.attr_name = self.get_chunk(64, 2 * self.length_of_name
                    ).decode('utf-16')
        else:
            self.attr_length = self.get_uint_le(16)
            self.attr_offset = self.get_ushort_le(20)
            self.indexed = self.get_ubyte(22)
            if self.length_of_name > 0:
                self.attr_name = self.get_chunk(24, 2 * self.length_of_name
                    ).decode('utf-16')

from rawdisk.util.rawstruct import RawStruct


class MftAttrHeader(RawStruct):
    """Represents MFT attribute header.

    Attributes:
        type (uint): Attribute type.
        length (uint): Attribute length (including this header).
        non_resident_flag (ubyte): Non-resident flag (0 - resident,             1 - otherwise).
        length_of_name (ubyte): If attribute has name, this is name         length in bytes.
        offset_to_name (ushort): Offset to attribute's name in bytes.
        attr_name (unicode): Attribuet's name (if it has one).
        flags (ushort): The attribute flags (COMPRESSION_MASK (0x00FF),             SPARSE (0x8000), ENCRYPTED (0x4000)).
        identifier (ushort): The unique identifier for this attribute         in the file record.

        Resident attribute:
        attr_length (uint): The size of the attribute value, in bytes.
        attr_offset (ushort): The offset to the value from the start of         the attribute record, in bytes.
        indexed (ubyte): Indexed flag??

        Non-resident attribute:
        lowest_vcn (ulonglong): The lowest virtual cluster number (VCN)         covered by this attribute record.
        highest_vcn (ulonglong): The highest VCN covered by this         attribute record.
        data_run_offset (ushort): The offset to the mapping         pairs array from the start of the attribute record, in bytes.
        comp_unit_size (ushort): Compression unit size = 2 x clusters.         0 implies uncompressed.
        alloc_size (ulonglong): The allocated size of the file, in bytes.         This value is an even multiple of the cluster size.         This member is not valid if the LowestVcn member is nonzero.
        real_size (ulonglong): The file size (highest byte that can be             read plus 1), in bytes.         This member is not valid if LowestVcn is nonzero.
        data_size (ulonglong): The valid data length (highest initialized             byte plus 1), in bytes. This value is rounded to the nearest         cluster boundary. This member is not valid if LowestVcn is nonzero.


    See More:
        | http://ftp.kolibrios.org/users/Asper/docs/NTFS/ntfsdoc.html#concept_attribute_header
        | http://msdn.microsoft.com/en-us/library/bb470039(v=vs.85).aspx
    """

    def __init__(self, data):
        RawStruct.__init__(self, data)
        self.type = self.get_uint_le(0)
        self.length = self.get_uint_le(4)
        self.non_resident_flag = self.get_ubyte(8)
        self.length_of_name = self.get_ubyte(9)
        self.offset_to_name = self.get_ushort_le(10)
        self.flags = self.get_ushort_le(12)
        self.identifier = self.get_ushort_le(14)
        if self.non_resident_flag:
            self.lowest_vcn = self.get_ulonglong_le(16)
            self.highest_vcn = self.get_ulonglong_le(24)
            self.data_run_offset = self.get_ushort_le(32)
            self.comp_unit_size = self.get_ushort_le(34)
            self.alloc_size = self.get_ulonglong_le(40)
            self.real_size = self.get_ulonglong_le(48)
            self.data_size = self.get_ulonglong_le(56)
            if self.length_of_name > 0:
                self.attr_name = self.get_chunk(64, 2 * self.length_of_name
                    ).decode('utf-16')
        else:
            self.attr_length = self.get_uint_le(16)
            self.attr_offset = self.get_ushort_le(20)
            self.indexed = self.get_ubyte(22)
            if self.length_of_name > 0:
                self.attr_name = self.get_chunk(24, 2 * self.length_of_name
                    ).decode('utf-16')

# -*- coding: utf-8 -*-


from rawdisk.util.rawstruct import RawStruct


class MftAttrHeader(RawStruct):
    """Represents MFT attribute header.

    Attributes:
        type (uint): Attribute type.
        length (uint): Attribute length (including this header).
        non_resident_flag (ubyte): Non-resident flag (0 - resident, \
            1 - otherwise).
        length_of_name (ubyte): If attribute has name, this is name \
        length in bytes.
        offset_to_name (ushort): Offset to attribute's name in bytes.
        attr_name (unicode): Attribuet's name (if it has one).
        flags (ushort): The attribute flags (COMPRESSION_MASK (0x00FF), \
            SPARSE (0x8000), ENCRYPTED (0x4000)).
        identifier (ushort): The unique identifier for this attribute \
        in the file record.

        Resident attribute:
        attr_length (uint): The size of the attribute value, in bytes.
        attr_offset (ushort): The offset to the value from the start of \
        the attribute record, in bytes.
        indexed (ubyte): Indexed flag??

        Non-resident attribute:
        lowest_vcn (ulonglong): The lowest virtual cluster number (VCN) \
        covered by this attribute record.
        highest_vcn (ulonglong): The highest VCN covered by this \
        attribute record.
        data_run_offset (ushort): The offset to the mapping \
        pairs array from the start of the attribute record, in bytes.
        comp_unit_size (ushort): Compression unit size = 2 x clusters. \
        0 implies uncompressed.
        alloc_size (ulonglong): The allocated size of the file, in bytes. \
        This value is an even multiple of the cluster size. \
        This member is not valid if the LowestVcn member is nonzero.
        real_size (ulonglong): The file size (highest byte that can be \
            read plus 1), in bytes. \
        This member is not valid if LowestVcn is nonzero.
        data_size (ulonglong): The valid data length (highest initialized \
            byte plus 1), in bytes. This value is rounded to the nearest \
        cluster boundary. This member is not valid if LowestVcn is nonzero.


    See More:
        | http://ftp.kolibrios.org\
/users/Asper/docs/NTFS/ntfsdoc.html#concept_attribute_header
        | http://msdn.microsoft.com/en-us/library/bb470039(v=vs.85).aspx
    """
    def __init__(self, data):
        RawStruct.__init__(self, data)
        self.type = self.get_uint_le(0)
        self.length = self.get_uint_le(0x4)
        self.non_resident_flag = self.get_ubyte(0x08)   # 0 - resident, 1 - not
        self.length_of_name = self.get_ubyte(0x09)      # Used only for ADS
        self.offset_to_name = self.get_ushort_le(0x0A)     # Used only for ADS

        # (Compressed, Encrypted, Sparse)
        self.flags = self.get_ushort_le(0x0C)
        self.identifier = self.get_ushort_le(0x0E)

        if (self.non_resident_flag):
            # Attribute is Non-Resident
            self.lowest_vcn = self.get_ulonglong_le(0x10)
            self.highest_vcn = self.get_ulonglong_le(0x18)
            self.data_run_offset = self.get_ushort_le(0x20)
            self.comp_unit_size = self.get_ushort_le(0x22)
            # 4 byte 0x00 padding @ 0x24
            self.alloc_size = self.get_ulonglong_le(0x28)
            self.real_size = self.get_ulonglong_le(0x30)
            self.data_size = self.get_ulonglong_le(0x38)

            if (self.length_of_name > 0):
                self.attr_name = self.get_chunk(
                    0x40, 2 * self.length_of_name).decode('utf-16')
                # print self.attr_name.decode('utf-16')
        else:
            # Attribute is Resident
            self.attr_length = self.get_uint_le(0x10)
            self.attr_offset = self.get_ushort_le(0x14)
            self.indexed = self.get_ubyte(0x16)
            if (self.length_of_name > 0):
                self.attr_name = self.get_chunk(
                    0x18, 2 * self.length_of_name).decode('utf-16')
                # print self.attr_name.decode('utf-16')
            # The rest byte is 0x00 padding
            # print "Attr Offset: 0x%x" % (self.attr_offset)
