コード例 #1
0
    def exportBinBlocksXMLTree(self):
        """ Export the file data into BIN files with XML glue
        """
        elem = self.exportXMLRoot()

        for ident, block in self.blocks.items():
            if (self.po.verbose > 0):
                print("{}: Writing BIN block {}".format(self.src_fname, ident))
            subelem = block.exportXMLTree(simple_bin=True)
            elem.append(subelem)

        ET.pretty_element_tree_heap(elem)
        return elem
コード例 #2
0
    def exportXMLTree(self):
        """ Export the file data into XML tree
        """
        elem = self.exportXMLRoot()

        for ident, block in self.blocks.items():
            if (self.po.verbose > 0):
                print("{}: Writing block {}".format(self.src_fname, ident))
            subelem = block.exportXMLTree()
            elem.append(subelem)

        ET.pretty_element_tree_heap(elem)
        return elem
コード例 #3
0
ファイル: LVrsrcontainer.py プロジェクト: ttonych/pylabview
 def exportXMLOrder(self, elem):
     if self.order_names is None:
         return
     order_elem = ET.SubElement(elem,"SpecialOrder")
     comment_elem = ET.Comment(" {:s} ".format("Provides information on how items were ordered in the RSRC file"))
     order_elem.append(comment_elem)
     if self.order_names is not None:
         subelem = ET.SubElement(order_elem,"Names")
         for blockref in self.order_names:
             pretty_ident = getPrettyStrFromRsrcType(blockref[0])
             blkref_elem = ET.Element(pretty_ident)
             blkref_elem.set("Index", str(blockref[1]))
             subelem.append(blkref_elem)
     pass
コード例 #4
0
    def exportXMLRoot(self):
        """ Creates root of the XML export tree
        """
        ver = self.getFileVersion()
        elem = ET.Element('RSRC')
        elem.set("FormatVersion", "{:d}".format(self.fmtver))
        rsrc_type_id = getRsrcTypeForFileType(self.ftype)
        elem.set("Type", rsrc_type_id.decode('ascii'))
        elem.set("Encoding", self.textEncoding)

        if self.ftype == FILE_FMT_TYPE.LLB or isSmallerVersion(ver, 7, 0, 0):
            dataset_int1 = self.binflsthead.dataset_int1
        else:
            dataset_int1 = None
        if dataset_int1 is not None:
            elem.set("Int1", "0x{:08X}".format(dataset_int1))

        # The value is verified to be used in LV6.0.1, unused in LV8.6
        if self.ftype == FILE_FMT_TYPE.LLB or isSmallerVersion(ver, 7, 0, 0):
            dataset_int2 = self.binflsthead.dataset_int2
        else:
            dataset_int2 = None
        if dataset_int2 is not None:
            elem.set("Int2", "0x{:08X}".format(dataset_int2))

        return elem
コード例 #5
0
ファイル: LVclasses.py プロジェクト: ttonych/pylabview
    def exportXML(self, obj_elem, fname_base):
        obj_elem.set("Ident",  getPrettyStrFromRsrcType(self.ident))
        obj_elem.set("TpIdent",  self.tpident.decode(encoding='ascii'))
        for text_val in self.content:
            subelem = ET.SubElement(obj_elem,"String")

            pretty_string = text_val.decode(self.vi.textEncoding)
            subelem.text = pretty_string
        pass
コード例 #6
0
ファイル: LVclasses.py プロジェクト: ttonych/pylabview
    def exportXML(self, obj_elem, fname_base):
        obj_elem.set("Ident",  getPrettyStrFromRsrcType(self.ident))
        obj_elem.set("TpVal",  "{:d}".format(self.tpval))
        if self.canZeroFill:
            obj_elem.set("ZeroFill", "True")
        for text_val in self.content:
            subelem = ET.SubElement(obj_elem,"String")

            pretty_string = text_val.decode(self.vi.textEncoding)
            subelem.text = pretty_string
        pass
コード例 #7
0
ファイル: LVclasses.py プロジェクト: ttonych/pylabview
    def exportXML(self, obj_elem, fname_base):
        obj_elem.tag = type(self).__name__
        obj_elem.set("HasVarItem2", "{:d}".format(self.hasvaritem2))
        if self.hasvaritem2 != 0:
            obj_elem.set("VarType2", "{:d}".format(self.vartype2))
        # Check whether we want to store version
        auto_ver = self.vi.getFileVersion()
        if all(self.version[k] == auto_ver[k] for k in ('major','minor','bugfix','stage','build','flags')):
            autoVersion = True
        else:
            autoVersion = False
        if autoVersion:
            obj_elem.set("Version", "{:s}".format("auto"))
        else:
            subelem = ET.SubElement(obj_elem,"Version")
            subelem.set("Major", "{:d}".format(self.version['major']))
            subelem.set("Minor", "{:d}".format(self.version['minor']))
            subelem.set("Bugfix", "{:d}".format(self.version['bugfix']))
            subelem.set("Stage", "{:s}".format(self.version['stage_text']))
            subelem.set("Build", "{:d}".format(self.version['build']))
            subelem.set("Flags", "0x{:X}".format(self.version['flags']))
        idx = -1
        for clientTD in self.clients2:
            if clientTD.index != -1:
                continue
            idx += 1
            fname_cli = "{:s}_{:04d}".format(fname_base, idx)
            subelem = ET.SubElement(obj_elem,"DataType")

            subelem.set("Index", str(idx))
            subelem.set("Type", stringFromValEnumOrInt(LVdatatype.TD_FULL_TYPE, clientTD.nested.otype))

            clientTD.nested.exportXML(subelem, fname_cli)
            clientTD.nested.exportXMLFinish(subelem)

        if len(self.attrs) > 0:
            attrs_elem = ET.SubElement(obj_elem,"Attributes")
            for attrib in self.attrs:
                subelem = ET.SubElement(attrs_elem,"Object")

                subelem.set("Name", attrib.name.decode(encoding=self.vi.textEncoding))
                attrib.value.exportXML(subelem, fname_base)

        if self.allowFillValue and self.hasvaritem2 and len(self.datafill) > 0:
            df_elem = ET.SubElement(obj_elem,"DataFill")
            for df in self.datafill:
                df_subelem = ET.SubElement(df_elem, df.getXMLTagName())

                df.exportXML(df_subelem, fname_base)
        pass
コード例 #8
0
    def exportXMLRoot(self):
        """ Creates root of the XML export tree
        """
        elem = ET.Element('RSRC')
        rsrc_type_id = getRsrcTypeForFileType(self.ftype)
        elem.set("Type", rsrc_type_id.decode('ascii'))
        elem.set("Encoding", self.textEncoding)

        if self.ftype == FILE_FMT_TYPE.LLB:
            dataset_int1 = self.binflsthead.dataset_int1
        else:
            dataset_int1 = None
        if dataset_int1 is not None:
            elem.set("Int1", "0x{:08X}".format(dataset_int1))

        if self.ftype == FILE_FMT_TYPE.LLB:
            dataset_int2 = self.binflsthead.dataset_int2
        else:
            dataset_int2 = None
        if dataset_int2 is not None:
            elem.set("Int2", "0x{:08X}".format(dataset_int2))

        return elem
コード例 #9
0
def main():
    """ Main executable function.

    Its task is to parse command line options and call a function which performs requested command.
    """
    # Parse command line options

    parser = argparse.ArgumentParser(description=__doc__)

    parser.add_argument('-i',
                        '--rsrc',
                        '--vi',
                        default="",
                        type=str,
                        help="name of the LabView RSRC file, VI or other")

    parser.add_argument('-m', '--xml', default="", type=str,
            help="name of the main XML file of extracted VI dataset;" \
            "default is RSRC file name with extension changed to xml")

    parser.add_argument(
        '-v',
        '--verbose',
        action='count',
        default=0,
        help="increases verbosity level; max level is set by -vvv")

    parser.add_argument(
        '-t',
        '--textcp',
        default="mac_roman",
        type=str,
        help=
        "Text encoding used while loading VI file (default is \"%(default)s\")"
    )

    parser.add_argument('--raw-connectors', action='store_true',
            help="extract all connectors into raw binary files instead of pure XML" \
            " (works only with --extract command)")

    parser.add_argument('--print-map', choices=["RSRC","VCTP","DFDS"],
            help="print map for whole file (RSRC) or section (VCTP,DFDS);" \
            " the map contains offsets at which things are within the file;" \
            " for sections which are compressed within RSRC file, specific" \
            " offsets can only be assigned after dumping it to bin")

    parser.add_argument('--keep-names', action='store_true',
            help="extract files to names indicated by RSRC content" \
            " (works with --extract and --dump commands; useful for LLBs)")

    subparser = parser.add_mutually_exclusive_group(required=True)

    subparser.add_argument('-l',
                           '--list',
                           action='store_true',
                           help="list content of RSRC file")

    subparser.add_argument('-d', '--dump', action='store_true',
            help="dump items from RSRC file into XML and BINs, with minimal" \
            " parsing of the data inside")

    subparser.add_argument('-x', '--extract', action='store_true',
            help="extract content of RSRC file into XMLs, parsing all blocks" \
            " which structure is known")

    subparser.add_argument('-c',
                           '--create',
                           action='store_true',
                           help="create RSRC file using information from XMLs")

    subparser.add_argument('-n',
                           '--info',
                           action='store_true',
                           help="print general information about RSRC file")

    subparser.add_argument('-p', '--password', default=None, type=str,
            help="change password and re-compute checksums within RSRC file;" \
            " save changes in-place, to the RSRC file")

    subparser.add_argument('--version',
                           action='version',
                           version="%(prog)s {version} by {author}".format(
                               version=__version__, author=__author__),
                           help="display version information and exit")

    po = parser.parse_args()

    po.typedesc_list_limit = 4095
    po.array_data_limit = (2**28) - 1

    # Store base name - without path and extension
    if len(po.xml) > 0:
        po.filebase = os.path.splitext(os.path.basename(po.xml))[0]
    elif len(po.rsrc) > 0:
        po.filebase = os.path.splitext(os.path.basename(po.rsrc))[0]
    else:
        raise FileNotFoundError(
            "Input file was not provided neither as RSRC or XML.")

    if po.list:

        if len(po.rsrc) == 0:
            raise FileNotFoundError(
                "Only RSRC file listing is currently supported.")

        if (po.verbose > 0):
            print("{}: Starting file parse for RSRC listing".format(po.rsrc))
        with open(po.rsrc, "rb") as rsrc_fh:
            vi = VI(po, rsrc_fh=rsrc_fh, text_encoding=po.textcp)

        print("{}\t{}".format("ident", "content"))
        for ident, block in vi.blocks.items():
            pretty_ident = block.ident.decode(encoding='UTF-8')
            print("{}\t{}".format(pretty_ident, str(block)))

    elif po.dump:

        if len(po.xml) == 0:
            po.xml = po.filebase + ".xml"
        if len(po.rsrc) == 0:
            po.rsrc = getExistingRSRCFileWithBase(po.filebase)
        if len(po.rsrc) == 0:
            raise FileNotFoundError(
                "No supported RSRC file was found despite checking all extensions."
            )

        if (po.verbose > 0):
            print("{}: Starting file parse for RSRC dumping".format(po.rsrc))
        with open(po.rsrc, "rb") as rsrc_fh:
            vi = VI(po, rsrc_fh=rsrc_fh, text_encoding=po.textcp)

            root = vi.exportBinBlocksXMLTree()

            if po.print_map is not None:
                vi.printRSRCMap()

        if (po.verbose > 0):
            print("{}: Writing binding XML".format(po.xml))
        tree = ET.ElementTree(root)
        with open(po.xml, "wb") as xml_fh:
            tree.write(xml_fh, encoding='utf-8', xml_declaration=True)

    elif po.extract:

        if len(po.xml) == 0:
            po.xml = po.filebase + ".xml"
        if len(po.rsrc) == 0:
            po.rsrc = getExistingRSRCFileWithBase(po.filebase)
        if len(po.rsrc) == 0:
            raise FileNotFoundError(
                "No supported RSRC file was found despite checking all extensions."
            )

        if (po.verbose > 0):
            print("{}: Starting file parse for RSRC extraction".format(
                po.rsrc))
        with open(po.rsrc, "rb") as rsrc_fh:
            vi = VI(po, rsrc_fh=rsrc_fh, text_encoding=po.textcp)

            root = vi.exportXMLTree()

            if po.print_map is not None:
                vi.printRSRCMap()

        if (po.verbose > 0):
            print("{}: Writing binding XML".format(po.xml))
        tree = ET.ElementTree(root)
        with open(po.xml, "wb") as xml_fh:
            tree.write(xml_fh, encoding='utf-8', xml_declaration=True)

    elif po.create:

        if len(po.xml) == 0:
            po.xml = po.filebase + ".xml"

        if (po.verbose > 0):
            print("{}: Starting file parse for RSRC creation".format(po.rsrc))
        tree = ET.parse(po.xml)
        vi = VI(po, xml_root=tree.getroot(), text_encoding=po.textcp)

        if len(po.rsrc) == 0:
            po.rsrc = po.filebase + "." + getFileExtByType(vi.ftype)

        with open(po.rsrc, "wb") as rsrc_fh:
            vi.saveRSRC(rsrc_fh)

    elif po.password is not None:

        if len(po.rsrc) == 0:
            raise FileNotFoundError(
                "Only RSRC file password change is currently supported.")

        if (po.verbose > 0):
            print("{}: Starting file parse for password change".format(
                po.rsrc))
        with open(po.rsrc, "rb") as rsrc_fh:
            vi = VI(po, rsrc_fh=rsrc_fh, text_encoding=po.textcp)
            vi.forceCompleteReadRSRC()

        BDPW = vi.get_or_raise('BDPW')
        if BDPW is not None:
            print("{:s}: Previous password data".format(po.rsrc))
            print("  password md5: {:s}".format(BDPW.password_md5.hex()))
            print("  hash_1      : {:s}".format(BDPW.hash_1.hex()))
            print("  hash_2      : {:s}".format(BDPW.hash_2.hex()))
            password_md5 = BDPW.password_md5

        BDPW = vi.setNewPassword(password_text=po.password)
        if BDPW is not None:
            print("{:s}: New password data".format(po.rsrc))
            print("  password md5: {:s}".format(BDPW.password_md5.hex()))
            print("  hash_1      : {:s}".format(BDPW.hash_1.hex()))
            print("  hash_2      : {:s}".format(BDPW.hash_2.hex()))

        with open(po.rsrc, "wb") as rsrc_fh:
            vi.saveRSRC(rsrc_fh)

    else:

        raise NotImplementedError('Unsupported command.')