summaryrefslogtreecommitdiffstats
path: root/BaseTools/Source/Python/FMMT/FMMT.py
blob: 26fc4c5792c42686b85b50dcdf06ff803ba3da23 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# @file
#  Firmware Module Management Tool.
#
#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
#
#  SPDX-License-Identifier: BSD-2-Clause-Patent
#
##

# Import Modules
#
import argparse
from core.FMMTOperation import *

parser = argparse.ArgumentParser(description='''
View the Binary Structure of FD/FV/Ffs/Section, and Delete/Extract/Add/Replace a Ffs from/into a FV.
''')
parser.add_argument("--version", action="version", version='%(prog)s Version 1.0',
                    help="Print debug information.")
parser.add_argument("-v", "--View", dest="View", nargs='+',
                    help="View each FV and the named files within each FV: '-v inputfile outputfile, inputfiletype(.Fd/.Fv/.ffs/.sec)'")
parser.add_argument("-d", "--Delete", dest="Delete", nargs='+',
                    help="Delete a Ffs from FV: '-d inputfile TargetFvName(Optional) TargetFfsName outputfile\
                        If not given TargetFvName, all the existed target Ffs will be deleted'")
parser.add_argument("-e", "--Extract", dest="Extract", nargs='+',
                    help="Extract a Ffs Info: '-e inputfile TargetFvName(Optional) TargetFfsName outputfile\
                        If not given TargetFvName, the first found target Ffs will be extracted.\
                        If only given TargetFvName, not given TargetFfsName, the TargetFv will be extracted to output file'")
parser.add_argument("-a", "--Add", dest="Add", nargs='+',
                    help="Add a Ffs into a FV:'-a inputfile TargetFvName newffsfile outputfile'")
parser.add_argument("-r", "--Replace", dest="Replace", nargs='+',
                    help="Replace a Ffs in a FV: '-r inputfile TargetFvName(Optional) TargetFfsName newffsfile outputfile\
                        If not given TargetFvName, all the existed target Ffs will be replaced with new Ffs file)'")
parser.add_argument("-l", "--LayoutFileName", dest="LayoutFileName", nargs='+',
                    help="The output file which saves Binary layout: '-l xxx.txt'/'-l xxx.json'\
                        If only provide file format as 'txt', \
                        the file will be generated with default name (Layout_'InputFileName'.txt). \
                        Currently supports two formats: json, txt. More formats will be added in the future")
parser.add_argument("-c", "--ConfigFilePath", dest="ConfigFilePath", nargs='+',
                    help="Provide the target FmmtConf.ini file path: '-c C:\Code\FmmtConf.ini' \
                        FmmtConf file saves the target guidtool used in compress/uncompress process.\
                        If do not provide, FMMT tool will search the inputfile folder for FmmtConf.ini firstly, if not found,\
                        the FmmtConf.ini saved in FMMT tool's folder will be used as default.")
parser.add_argument("-s", "--ShrinkFv", dest="ShrinkFv", nargs='+',
                    help="Shrink the Fv file: '-s InputFvfile OutputFvfile")

def print_banner():
    print("")

class FMMT():
    def __init__(self) -> None:
        self.firmware_packet = {}

    def SetConfigFilePath(self, configfilepath:str) -> str:
        os.environ['FmmtConfPath'] = os.path.abspath(configfilepath)

    def SetDestPath(self, inputfile:str) -> str:
        os.environ['FmmtConfPath'] = ''
        self.dest_path = os.path.dirname(os.path.abspath(inputfile))
        old_env = os.environ['PATH']
        os.environ['PATH'] = self.dest_path + os.pathsep + old_env

    def CheckFfsName(self, FfsName:str) -> str:
        try:
            return uuid.UUID(FfsName)
        except:
            return FfsName

    def GetFvName(self, FvName:str) -> str:
        try:
            return uuid.UUID(FvName)
        except:
            return FvName

    def View(self, inputfile: str, layoutfilename: str=None, outputfile: str=None) -> None:
        # ViewFile(inputfile, ROOT_TYPE, logfile, outputfile)
        self.SetDestPath(inputfile)
        filetype = os.path.splitext(inputfile)[1].lower()
        if filetype == '.fd':
            ROOT_TYPE = ROOT_TREE
        elif filetype == '.fv':
            ROOT_TYPE = ROOT_FV_TREE
        elif filetype == '.ffs':
            ROOT_TYPE = ROOT_FFS_TREE
        elif filetype == '.sec':
            ROOT_TYPE = ROOT_SECTION_TREE
        elif filetype == '.elf':
            ROOT_TYPE = ROOT_ELF_TREE
        else:
            ROOT_TYPE = ROOT_TREE
        ViewFile(inputfile, ROOT_TYPE, layoutfilename, outputfile)

    def Delete(self, inputfile: str, TargetFfs_name: str, outputfile: str, Fv_name: str=None) -> None:
        self.SetDestPath(inputfile)
        if Fv_name:
            DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name), outputfile, self.GetFvName(Fv_name))
        else:
            DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name), outputfile)

    def Extract(self, inputfile: str, Ffs_name: str, outputfile: str, Fv_name: str=None) -> None:
        self.SetDestPath(inputfile)
        if Fv_name:
            ExtractFfs(inputfile, self.CheckFfsName(Ffs_name), outputfile, self.GetFvName(Fv_name))
        else:
            ExtractFfs(inputfile, self.CheckFfsName(Ffs_name), outputfile)

    def Add(self, inputfile: str, Fv_name: str, newffsfile: str, outputfile: str) -> None:
        self.SetDestPath(inputfile)
        AddNewFfs(inputfile, self.CheckFfsName(Fv_name), newffsfile, outputfile)

    def Replace(self,inputfile: str, Ffs_name: str, newffsfile: str, outputfile: str, Fv_name: str=None) -> None:
        self.SetDestPath(inputfile)
        if Fv_name:
            ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name), newffsfile, outputfile, self.GetFvName(Fv_name))
        else:
            ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name), newffsfile, outputfile)

    def Shrink(self,inputfile: str, outputfile: str) -> None:
        self.SetDestPath(inputfile)
        ShrinkFv(inputfile, outputfile)

def main():
    args=parser.parse_args()
    status=0

    try:
        fmmt=FMMT()
        if args.ConfigFilePath:
            fmmt.SetConfigFilePath(args.ConfigFilePath[0])
        if args.View:
            if args.LayoutFileName:
                fmmt.View(args.View[0], args.LayoutFileName[0])
            else:
                fmmt.View(args.View[0])
        elif args.Delete:
            if len(args.Delete) == 4:
                fmmt.Delete(args.Delete[0],args.Delete[2],args.Delete[3],args.Delete[1])
            else:
                fmmt.Delete(args.Delete[0],args.Delete[1],args.Delete[2])
        elif args.Extract:
            if len(args.Extract) == 4:
                fmmt.Extract(args.Extract[0],args.Extract[2],args.Extract[3], args.Extract[1])
            else:
                fmmt.Extract(args.Extract[0],args.Extract[1],args.Extract[2])
        elif args.Add:
            fmmt.Add(args.Add[0],args.Add[1],args.Add[2],args.Add[3])
        elif args.Replace:
            if len(args.Replace) == 5:
                fmmt.Replace(args.Replace[0],args.Replace[2],args.Replace[3],args.Replace[4],args.Replace[1])
            else:
                fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[3])
        elif args.ShrinkFv:
            fmmt.Shrink(args.ShrinkFv[0], args.ShrinkFv[1])
        else:
            parser.print_help()
    except Exception as e:
        print(e)

    return status


if __name__ == "__main__":
    exit(main())