]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/FMMT/core/BiosTree.py
BaseTools: Add FMMT Python Tool
[mirror_edk2.git] / BaseTools / Source / Python / FMMT / core / BiosTree.py
diff --git a/BaseTools/Source/Python/FMMT/core/BiosTree.py b/BaseTools/Source/Python/FMMT/core/BiosTree.py
new file mode 100644 (file)
index 0000000..d8fa474
--- /dev/null
@@ -0,0 +1,198 @@
+## @file\r
+# This file is used to define the Bios layout tree structure and related operations.\r
+#\r
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+##\r
+import collections\r
+from FirmwareStorageFormat.Common import *\r
+from utils.FmmtLogger import FmmtLogger as logger\r
+\r
+ROOT_TREE = 'ROOT'\r
+ROOT_FV_TREE = 'ROOT_FV_TREE'\r
+ROOT_FFS_TREE = 'ROOT_FFS_TREE'\r
+ROOT_SECTION_TREE = 'ROOT_SECTION_TREE'\r
+\r
+FV_TREE = 'FV'\r
+DATA_FV_TREE = 'DATA_FV'\r
+FFS_TREE = 'FFS'\r
+FFS_PAD = 'FFS_PAD'\r
+FFS_FREE_SPACE = 'FFS_FREE_SPACE'\r
+SECTION_TREE = 'SECTION'\r
+SEC_FV_TREE = 'SEC_FV_IMAGE'\r
+BINARY_DATA = 'BINARY'\r
+\r
+RootType = [ROOT_TREE, ROOT_FV_TREE, ROOT_FFS_TREE, ROOT_SECTION_TREE]\r
+FvType = [FV_TREE, SEC_FV_TREE]\r
+FfsType = FFS_TREE\r
+SecType = SECTION_TREE\r
+\r
+class BIOSTREE:\r
+    def __init__(self, NodeName: str) -> None:\r
+        self.key = NodeName\r
+        self.type = None\r
+        self.Data = None\r
+        self.Child = []\r
+        self.Findlist = []\r
+        self.Parent = None\r
+        self.NextRel = None\r
+        self.LastRel = None\r
+\r
+    def HasChild(self) -> bool:\r
+        if self.Child == []:\r
+            return False\r
+        else:\r
+            return True\r
+\r
+    def isFinalChild(self) -> bool:\r
+        ParTree = self.Parent\r
+        if ParTree:\r
+            if ParTree.Child[-1] == self:\r
+                return True\r
+        return False\r
+\r
+    # FvTree.insertChild()\r
+    def insertChild(self, newNode, pos: int=None) -> None:\r
+        if len(self.Child) == 0:\r
+            self.Child.append(newNode)\r
+        else:\r
+            if not pos:\r
+                LastTree = self.Child[-1]\r
+                self.Child.append(newNode)\r
+                LastTree.NextRel = newNode\r
+                newNode.LastRel = LastTree\r
+            else:\r
+                newNode.NextRel = self.Child[pos-1].NextRel\r
+                newNode.LastRel = self.Child[pos].LastRel\r
+                self.Child[pos-1].NextRel = newNode\r
+                self.Child[pos].LastRel = newNode\r
+                self.Child.insert(pos, newNode)\r
+        newNode.Parent = self\r
+\r
+    # lastNode.insertRel(newNode)\r
+    def insertRel(self, newNode) -> None:\r
+        if self.Parent:\r
+            parentTree = self.Parent\r
+            new_index = parentTree.Child.index(self) + 1\r
+            parentTree.Child.insert(new_index, newNode)\r
+        self.NextRel = newNode\r
+        newNode.LastRel = self\r
+\r
+    def deleteNode(self, deletekey: str) -> None:\r
+        FindStatus, DeleteTree = self.FindNode(deletekey)\r
+        if FindStatus:\r
+            parentTree = DeleteTree.Parent\r
+            lastTree = DeleteTree.LastRel\r
+            nextTree = DeleteTree.NextRel\r
+            if parentTree:\r
+                index = parentTree.Child.index(DeleteTree)\r
+                del parentTree.Child[index]\r
+            if lastTree and nextTree:\r
+                lastTree.NextRel = nextTree\r
+                nextTree.LastRel = lastTree\r
+            elif lastTree:\r
+                lastTree.NextRel = None\r
+            elif nextTree:\r
+                nextTree.LastRel = None\r
+            return DeleteTree\r
+        else:\r
+            logger.error('Could not find the target tree')\r
+            return None\r
+\r
+    def FindNode(self, key: str, Findlist: list) -> None:\r
+        if self.key == key or (self.Data and self.Data.Name == key) or (self.type == FFS_TREE and self.Data.UiName == key):\r
+            Findlist.append(self)\r
+        for item in self.Child:\r
+            item.FindNode(key, Findlist)\r
+\r
+    def GetTreePath(self):\r
+        BiosTreePath = [self]\r
+        while self.Parent:\r
+            BiosTreePath.insert(0, self.Parent)\r
+            self = self.Parent\r
+        return BiosTreePath\r
+\r
+    def parserTree(self, TargetDict: dict=None, Info: list=None, space: int=0, ParFvId="") -> None:\r
+        Key = list(TargetDict.keys())[0]\r
+        if TargetDict[Key]["Type"] in RootType:\r
+            Info.append("Image File: {}".format(Key))\r
+            Info.append("FilesNum: {}".format(TargetDict.get(Key).get('FilesNum')))\r
+            Info.append("\n")\r
+        elif TargetDict[Key]["Type"] in FvType:\r
+            space += 2\r
+            if TargetDict[Key]["Type"] == SEC_FV_TREE:\r
+                Info.append("{}Child FV named {} of {}".format(space*" ", Key, ParFvId))\r
+                space += 2\r
+            else:\r
+                Info.append("FvId: {}".format(Key))\r
+                ParFvId = Key\r
+            Info.append("{}FvNameGuid: {}".format(space*" ", TargetDict.get(Key).get('FvNameGuid')))\r
+            Info.append("{}Attributes: {}".format(space*" ", TargetDict.get(Key).get('Attributes')))\r
+            Info.append("{}Total Volume Size: {}".format(space*" ", TargetDict.get(Key).get('Size')))\r
+            Info.append("{}Free Volume Size: {}".format(space*" ", TargetDict.get(Key).get('FreeSize')))\r
+            Info.append("{}Volume Offset: {}".format(space*" ", TargetDict.get(Key).get('Offset')))\r
+            Info.append("{}FilesNum: {}".format(space*" ", TargetDict.get(Key).get('FilesNum')))\r
+        elif TargetDict[Key]["Type"] in FfsType:\r
+            space += 2\r
+            if TargetDict.get(Key).get('UiName') != "b''":\r
+                Info.append("{}File: {} / {}".format(space*" ", Key, TargetDict.get(Key).get('UiName')))\r
+            else:\r
+                Info.append("{}File: {}".format(space*" ", Key))\r
+        if "Files" in list(TargetDict[Key].keys()):\r
+            for item in TargetDict[Key]["Files"]:\r
+                self.parserTree(item, Info, space, ParFvId)\r
+\r
+    def ExportTree(self,TreeInfo: dict=None) -> dict:\r
+        if TreeInfo is None:\r
+            TreeInfo =collections.OrderedDict()\r
+\r
+        if self.type == ROOT_TREE or self.type == ROOT_FV_TREE or self.type == ROOT_FFS_TREE or self.type == ROOT_SECTION_TREE:\r
+            key = str(self.key)\r
+            TreeInfo[self.key] = collections.OrderedDict()\r
+            TreeInfo[self.key]["Name"] = key\r
+            TreeInfo[self.key]["Type"] = self.type\r
+            TreeInfo[self.key]["FilesNum"] = len(self.Child)\r
+        elif self.type == FV_TREE or  self.type == SEC_FV_TREE:\r
+            key = str(self.Data.FvId)\r
+            TreeInfo[key] = collections.OrderedDict()\r
+            TreeInfo[key]["Name"] = key\r
+            if self.Data.FvId != self.Data.Name:\r
+                TreeInfo[key]["FvNameGuid"] = str(self.Data.Name)\r
+            TreeInfo[key]["Type"] = self.type\r
+            TreeInfo[key]["Attributes"] = hex(self.Data.Header.Attributes)\r
+            TreeInfo[key]["Size"] = hex(self.Data.Header.FvLength)\r
+            TreeInfo[key]["FreeSize"] = hex(self.Data.Free_Space)\r
+            TreeInfo[key]["Offset"] = hex(self.Data.HOffset)\r
+            TreeInfo[key]["FilesNum"] = len(self.Child)\r
+        elif self.type == FFS_TREE:\r
+            key = str(self.Data.Name)\r
+            TreeInfo[key] = collections.OrderedDict()\r
+            TreeInfo[key]["Name"] = key\r
+            TreeInfo[key]["UiName"] = '{}'.format(self.Data.UiName)\r
+            TreeInfo[key]["Version"] = '{}'.format(self.Data.Version)\r
+            TreeInfo[key]["Type"] = self.type\r
+            TreeInfo[key]["Size"] = hex(self.Data.Size)\r
+            TreeInfo[key]["Offset"] = hex(self.Data.HOffset)\r
+            TreeInfo[key]["FilesNum"] = len(self.Child)\r
+        elif self.type == SECTION_TREE and self.Data.Type == 0x02:\r
+            key = str(self.Data.Name)\r
+            TreeInfo[key] = collections.OrderedDict()\r
+            TreeInfo[key]["Name"] = key\r
+            TreeInfo[key]["Type"] = self.type\r
+            TreeInfo[key]["Size"] = hex(len(self.Data.OriData) + self.Data.HeaderLength)\r
+            TreeInfo[key]["DecompressedSize"] = hex(self.Data.Size)\r
+            TreeInfo[key]["Offset"] = hex(self.Data.HOffset)\r
+            TreeInfo[key]["FilesNum"] = len(self.Child)\r
+        elif self is not None:\r
+            key = str(self.Data.Name)\r
+            TreeInfo[key] = collections.OrderedDict()\r
+            TreeInfo[key]["Name"] = key\r
+            TreeInfo[key]["Type"] = self.type\r
+            TreeInfo[key]["Size"] = hex(self.Data.Size)\r
+            TreeInfo[key]["Offset"] = hex(self.Data.HOffset)\r
+            TreeInfo[key]["FilesNum"] = len(self.Child)\r
+\r
+        for item in self.Child:\r
+            TreeInfo[key].setdefault('Files',[]).append( item.ExportTree())\r
+\r
+        return TreeInfo\r
\ No newline at end of file