Esempio n. 1
0
def read_properties(entry):
    stream = entry.get('properties')
    if stream is None:
        raise Exception("can not find properties")

    s = stream.open()
    # read the whole stream
    f = BytesIO(s.read())

    byte_order = read_u8(f)
    if byte_order != 0x4c:
        raise NotImplementedError("be byteorder")
    version = read_u8(f)
    entry_count = read_u16le(f)

    props = []
    for i in range(entry_count):
        pid = read_u16le(f)
        format = read_u16le(f)
        byte_size = read_u16le(f)

        props.append([pid, format, byte_size])

    property_entries = {}
    for pid, format, byte_size in props:
        data = f.read(byte_size)
        property_entries[pid] = data

    return property_entries
Esempio n. 2
0
def read_set_index(entry):

    s = entry.open('r')
    # read the whole of the index
    f = BytesIO(s.read())

    count = read_u32le(f)
    next_free_key = read_u32le(f)
    last_free_key = read_u32le(f)
    key_pid = read_u16le(f)
    key_size = read_u8(f)
    assert key_size in (16, 32)

    references = []

    for i in range(count):
        local_key = read_u32le(f)
        ref_count = read_u32le(f)

        # not sure if ref count is actually used
        # doesn't apear to be
        assert ref_count == 1

        if key_size == 16:
            key = UUID(bytes_le=f.read(key_size))
        else:
            key = mobid.MobID(bytes_le=f.read(key_size))
        references.append((key, local_key))
        # references[key] = local_key

    return references
Esempio n. 3
0
def decode_weakref(data):
    f = BytesIO(data)
    weakref_index = read_u16le(f)
    key_pid = read_u16le(f)
    key_size = read_u8(f)
    assert key_size in (16, 32)
    if key_size == 16:
        ref = UUID(bytes_le=f.read(key_size))
    else:
        ref = key = MobID(bytes_le=f.read(key_size))
    return ref
Esempio n. 4
0
def read_weakref_array_index(entry):
    s = entry.open('r')
    # read the whole index
    f = BytesIO(s.read())

    count = read_u32le(f)
    weakref_index = read_u16le(f)
    key_pid = read_u16le(f)
    key_size = read_u8(f)
    assert key_size in (16, 32)
    references = []
    for i in range(count):
        if key_size == 16:
            key = UUID(bytes_le=f.read(key_size))
        else:
            key = key = MobID(bytes_le=f.read(key_size))
        references.append(key)
    return references
Esempio n. 5
0
def read_reference_properties(cfb):
    f = cfb.open("/referenced properties")

    byte_order = read_u8(f)
    if byte_order != 0x4c:
        raise NotImplementedError("be byteorder")

    path_count = read_u16le(f)
    pid_count = read_u32le(f)

    weakref_table = []
    path = []
    for i in range(pid_count):
        pid = read_u16le(f)
        if pid != 0:
            path.append(pid)
        else:
            weakref_table.append(path)
            path = []
    assert len(weakref_table) == path_count
    return weakref_table
Esempio n. 6
0
def read_typedef(entry, types):
    p = read_properties(entry)
    name = decode_utf16le(p[NAME_PID])
    identification = UUID(bytes_le=p[IDENTIFICATION_PID])
    types['all'][identification] = name
    # description = decode_utf16le(p[DESCRIPTION_PID])
    # print(name, description)

    data = [identification]

    if entry.class_id == TypeDefInt:
        size = read_u8(BytesIO(p[TypeDefInt_Size]))
        signed = p[TypeDefInt_IsSigned] == b"\x01"
        data.extend([size, signed])
        types['ints'][name] = data

    elif entry.class_id == TypeDefStrongRef:
        ref_type = decode_weakref(p[TypeDefStrongRef_ReferencedType])
        data.extend([ref_type])
        types['strongrefs'][name] = data

    elif entry.class_id == TypeDefWeakRef:
        ref_type = decode_weakref(p[TypeDefWeakRef_ReferencedType])
        target_set = decode_auid_array(p[TypeDefWeakRef_TargetSet])
        data.extend([ref_type, target_set])
        types['weakrefs'][name] = data

    elif entry.class_id == TypeDefEnum:
        type = decode_weakref(p[TypeDefEnum_ElementType])
        names = decode_utf16_array(p[TypeDefEnum_ElementNames])

        # aafInt64Array
        values = p[TypeDefEnum_ElementValues]
        size = 8
        elements = len(values) // size
        values = unpack('<%dq' % elements, values)

        data.extend([type, dict(zip(values, names))])
        types['enums'][name] = data

    elif entry.class_id == TypeDefFixedArray:
        # aafUInt32
        elements = read_u32le(BytesIO(p[TypeDefFixedArray_ElementCount]))
        type = decode_weakref(p[TypeDefFixedArray_ElementType])
        data.extend([type, elements])
        types['fixed_arrays'][name] = data

    elif entry.class_id == TypeDefVariableArray:
        type = decode_weakref(p[TypeDefVariableArray_ElementType])
        data.extend([type])
        types['var_arrays'][name] = data

    elif entry.class_id == TypeDefSet:
        type = decode_weakref(p[TypeDefSet_ElementType])
        data.extend([type])
        types['sets'][name] = data

    elif entry.class_id == TypeDefString:
        type = decode_weakref(p[TypeDefString_ElementType])
        data.extend([type])
        types['strings'][name] = data

    elif entry.class_id == TypeDefStream:
        types['streams'][name] = data

    elif entry.class_id == TypeDefRecord:
        member_names = decode_utf16_array(p[TypeDefRecord_MemberNames])
        member_index_name = decode_utf16le(p[TypeDefRecord_MemberTypes])
        member_types = read_weakref_array_index(
            entry.get(member_index_name + " index"))
        data.append(list(zip(member_names, member_types)))
        types['records'][name] = data

    elif entry.class_id == TypeDefRename:
        type = decode_weakref(p[TypeDefRename_RenamedType])
        data.extend([type])
        types['renames'][name] = data

    elif entry.class_id == TypeDefExtendibleEnum:
        element_values = decode_auid_array(
            p[TypeDefExtendibleEnum_ElementValues])
        element_names = decode_utf16_array(
            p[TypeDefExtendibleEnum_ElementNames])
        data.extend([dict(zip(element_values, element_names))])
        types['extenums'][name] = data

    elif entry.class_id == TypeDefIndirect:
        types['indirects'][name] = data
    elif entry.class_id == TypeDefOpaque:
        types['opaques'][name] = data
    elif entry.class_id == TypeDefCharacter:
        types['chars'][name] = data
    else:
        raise ValueError("Unknown TypeDef: " + str(entry.class_id))