]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/PatchPcdValue/PatchPcdValue.py
BaseTools: DSC Components section support flexible PCD
[mirror_edk2.git] / BaseTools / Source / Python / PatchPcdValue / PatchPcdValue.py
index 69c824479071eaf4a95ee5ccc6980a76209fe09d..942ba88d200f98c70ba163443aa6727140666402 100644 (file)
-## @file
-# Patch value into the binary file.
-#
-# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
-# This program and the accompanying materials
-# are licensed and made available under the terms and conditions of the BSD License
-# which accompanies this distribution.  The full text of the license may be found at
-# http://opensource.org/licenses/bsd-license.php
-#
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-#
-
-##
-# Import Modules
-#
-import os
-import sys
-import re
-
-from optparse import OptionParser
-from optparse import make_option
-from Common.BuildToolError import *
-import Common.EdkLogger as EdkLogger
-from Common.BuildVersion import gBUILD_VERSION
-import array
-
-# Version and Copyright
-__version_number__ = ("0.10" + " " + gBUILD_VERSION)
-__version__ = "%prog Version " + __version_number__
-__copyright__ = "Copyright (c) 2010, Intel Corporation. All rights reserved."
-
-## PatchBinaryFile method
-#
-# This method mainly patches the data into binary file.
-# 
-# @param FileName    File path of the binary file
-# @param ValueOffset Offset value 
-# @param TypeName    DataType Name
-# @param Value       Value String
-# @param MaxSize     MaxSize value
-#
-# @retval 0     File is updated successfully.
-# @retval not 0 File is updated failed.
-#
-def PatchBinaryFile(FileName, ValueOffset, TypeName, ValueString, MaxSize=0):
-    #
-    # Length of Binary File
-    #
-    FileHandle = open (FileName, 'rb')
-    FileHandle.seek (0, 2)
-    FileLength = FileHandle.tell()
-    FileHandle.close()
-    #
-    # Unify string to upper string
-    #
-    TypeName = TypeName.upper()
-    #
-    # Get PCD value data length
-    #
-    ValueLength = 0
-    if TypeName == 'BOOLEAN':
-        ValueLength = 1
-    elif TypeName == 'UINT8':
-        ValueLength = 1
-    elif TypeName == 'UINT16':
-        ValueLength = 2
-    elif TypeName == 'UINT32':
-        ValueLength = 4
-    elif TypeName == 'UINT64':
-        ValueLength = 8
-    elif TypeName == 'VOID*':
-        if MaxSize == 0:
-            return OPTION_MISSING, "PcdMaxSize is not specified for VOID* type PCD."
-        ValueLength = int(MaxSize)
-    else:
-        return PARAMETER_INVALID,  "PCD type %s is not valid." %(CommandOptions.PcdTypeName)
-    #
-    # Check PcdValue is in the input binary file.
-    #
-    if ValueOffset + ValueLength > FileLength:
-        return PARAMETER_INVALID, "PcdOffset + PcdMaxSize(DataType) is larger than the input file size."
-    #
-    # Read binary file into array
-    #
-    FileHandle = open (FileName, 'rb')
-    ByteArray = array.array('B')
-    ByteArray.fromfile(FileHandle, FileLength)
-    FileHandle.close()
-    OrigByteList = ByteArray.tolist()
-    ByteList = ByteArray.tolist()
-    #
-    # Clear the data in file
-    #
-    for Index in range(ValueLength):
-        ByteList[ValueOffset + Index] = 0
-    #
-    # Patch value into offset
-    #
-    SavedStr = ValueString
-    ValueString = ValueString.upper()
-    ValueNumber = 0
-    if TypeName == 'BOOLEAN':
-        #
-        # Get PCD value for BOOLEAN data type
-        #
-        try:
-            if ValueString == 'TRUE':
-                ValueNumber = 1
-            elif ValueString == 'FALSE':
-                ValueNumber = 0
-            elif ValueString.startswith('0X'):
-                ValueNumber = int (ValueString, 16)
-            else:
-                ValueNumber = int (ValueString)
-            if ValueNumber != 0:
-                ValueNumber = 1
-        except:
-            return PARAMETER_INVALID, "PCD Value %s is not valid dec or hex string." %(ValueString)
-        #
-        # Set PCD value into binary data
-        #
-        ByteList[ValueOffset] = ValueNumber
-    elif TypeName in ['UINT8', 'UINT16', 'UINT32', 'UINT64']:
-        #
-        # Get PCD value for UINT* data type
-        #
-        try:
-            if ValueString.startswith('0X'):
-                ValueNumber = int (ValueString, 16)
-            else:
-                ValueNumber = int (ValueString)
-        except:
-            return PARAMETER_INVALID, "PCD Value %s is not valid dec or hex string." %(ValueString)
-        #
-        # Set PCD value into binary data
-        #
-        for Index in range(ValueLength):
-            ByteList[ValueOffset + Index] = ValueNumber % 0x100
-            ValueNumber = ValueNumber / 0x100
-    elif TypeName == 'VOID*':
-        ValueString = SavedStr
-        if ValueString.startswith('L"'):
-            #
-            # Patch Unicode String
-            #
-            Index = 0
-            for ByteString in ValueString[2:-1]:
-                #
-                # Reserve zero as unicode tail
-                #
-                if Index + 2 >= ValueLength:
-                    break
-                #
-                # Set string value one by one
-                #
-                ByteList[ValueOffset + Index] = ord(ByteString)
-                Index = Index + 2
-        elif ValueString.startswith("{") and ValueString.endswith("}"):
-            #
-            # Patch {0x1, 0x2, ...} byte by byte
-            #
-            ValueList = ValueString[1 : len(ValueString) - 1].split(', ')
-            Index = 0
-            try:
-                for ByteString in ValueList:
-                    if ByteString.upper().startswith('0X'):
-                        ByteValue = int(ByteString, 16)
-                    else:
-                        ByteValue = int(ByteString)
-                    ByteList[ValueOffset + Index] = ByteValue % 0x100
-                    Index = Index + 1
-                    if Index >= ValueLength:
-                        break
-            except:
-                return PARAMETER_INVALID, "PCD Value %s is not valid dec or hex string array." %(ValueString)
-        else:
-            #
-            # Patch ascii string 
-            #
-            Index = 0
-            for ByteString in ValueString[1:-1]:
-                #
-                # Reserve zero as string tail
-                #
-                if Index + 1 >= ValueLength:
-                    break
-                #
-                # Set string value one by one
-                #
-                ByteList[ValueOffset + Index] = ord(ByteString)
-                Index = Index + 1
-    #
-    # Update new data into input file.
-    #
-    if ByteList != OrigByteList:
-        ByteArray = array.array('B')
-        ByteArray.fromlist(ByteList)
-        FileHandle = open (FileName, 'wb')
-        ByteArray.tofile(FileHandle)
-        FileHandle.close()
-    return 0, "Patch Value into File %s successfully." %(FileName)
-
-## Parse command line options
-#
-# Using standard Python module optparse to parse command line option of this tool.
-#
-# @retval Options   A optparse.Values object containing the parsed options
-# @retval InputFile Path of file to be trimmed
-#
-def Options():
-    OptionList = [
-        make_option("-f", "--offset", dest="PcdOffset", action="store", type="int",
-                          help="Start offset to the image is used to store PCD value."),
-        make_option("-u", "--value", dest="PcdValue", action="store",
-                          help="PCD value will be updated into the image."),
-        make_option("-t", "--type", dest="PcdTypeName", action="store",
-                          help="The name of PCD data type may be one of VOID*,BOOLEAN, UINT8, UINT16, UINT32, UINT64."),
-        make_option("-s", "--maxsize", dest="PcdMaxSize", action="store", type="int",
-                          help="Max size of data buffer is taken by PCD value.It must be set when PCD type is VOID*."),
-        make_option("-v", "--verbose", dest="LogLevel", action="store_const", const=EdkLogger.VERBOSE,
-                          help="Run verbosely"),
-        make_option("-d", "--debug", dest="LogLevel", type="int",
-                          help="Run with debug information"),
-        make_option("-q", "--quiet", dest="LogLevel", action="store_const", const=EdkLogger.QUIET,
-                          help="Run quietly"),
-        make_option("-?", action="help", help="show this help message and exit"),
-    ]
-
-    # use clearer usage to override default usage message
-    UsageString = "%prog -f Offset -u Value -t Type [-s MaxSize] <input_file>"
-
-    Parser = OptionParser(description=__copyright__, version=__version__, option_list=OptionList, usage=UsageString)
-    Parser.set_defaults(LogLevel=EdkLogger.INFO)
-
-    Options, Args = Parser.parse_args()
-
-    # error check
-    if len(Args) == 0:
-        EdkLogger.error("PatchPcdValue", PARAMETER_INVALID, ExtraData=Parser.get_usage())
-
-    InputFile = Args[len(Args) - 1]
-    return Options, InputFile
-
-## Entrance method
-#
-# This method mainly dispatch specific methods per the command line options.
-# If no error found, return zero value so the caller of this tool can know
-# if it's executed successfully or not.
-#
-# @retval 0     Tool was successful
-# @retval 1     Tool failed
-#
-def Main():
-    try:
-        #
-        # Check input parameter
-        #
-        EdkLogger.Initialize()
-        CommandOptions, InputFile = Options()
-        if CommandOptions.LogLevel < EdkLogger.DEBUG_9:
-            EdkLogger.SetLevel(CommandOptions.LogLevel + 1)
-        else:
-            EdkLogger.SetLevel(CommandOptions.LogLevel)
-        if not os.path.exists (InputFile):
-            EdkLogger.error("PatchPcdValue", FILE_NOT_FOUND, ExtraData=InputFile)
-            return 1
-        if CommandOptions.PcdOffset == None or CommandOptions.PcdValue == None or CommandOptions.PcdTypeName == None:
-            EdkLogger.error("PatchPcdValue", OPTION_MISSING, ExtraData="PcdOffset or PcdValue of PcdTypeName is not specified.")
-            return 1
-        if CommandOptions.PcdTypeName.upper() not in ["BOOLEAN", "UINT8", "UINT16", "UINT32", "UINT64", "VOID*"]:
-            EdkLogger.error("PatchPcdValue", PARAMETER_INVALID, ExtraData="PCD type %s is not valid." %(CommandOptions.PcdTypeName))
-            return 1
-        if CommandOptions.PcdTypeName.upper() == "VOID*" and CommandOptions.PcdMaxSize == None:
-            EdkLogger.error("PatchPcdValue", OPTION_MISSING, ExtraData="PcdMaxSize is not specified for VOID* type PCD.")
-            return 1
-        #
-        # Patch value into binary image.
-        #
-        ReturnValue, ErrorInfo = PatchBinaryFile (InputFile, CommandOptions.PcdOffset, CommandOptions.PcdTypeName, CommandOptions.PcdValue, CommandOptions.PcdMaxSize)
-        if ReturnValue != 0:
-            EdkLogger.error("PatchPcdValue", ReturnValue, ExtraData=ErrorInfo)
-            return 1
-        return 0
-    except:
-        return 1
-
-if __name__ == '__main__':
-    r = Main()
-    sys.exit(r)
+## @file\r
+# Patch value into the binary file.\r
+#\r
+# Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+\r
+##\r
+# Import Modules\r
+#\r
+import Common.LongFilePathOs as os\r
+from Common.LongFilePathSupport import OpenLongFilePath as open\r
+import sys\r
+import re\r
+\r
+from optparse import OptionParser\r
+from optparse import make_option\r
+from Common.BuildToolError import *\r
+import Common.EdkLogger as EdkLogger\r
+from Common.BuildVersion import gBUILD_VERSION\r
+import array\r
+\r
+# Version and Copyright\r
+__version_number__ = ("0.10" + " " + gBUILD_VERSION)\r
+__version__ = "%prog Version " + __version_number__\r
+__copyright__ = "Copyright (c) 2010, Intel Corporation. All rights reserved."\r
+\r
+## PatchBinaryFile method\r
+#\r
+# This method mainly patches the data into binary file.\r
+# \r
+# @param FileName    File path of the binary file\r
+# @param ValueOffset Offset value \r
+# @param TypeName    DataType Name\r
+# @param Value       Value String\r
+# @param MaxSize     MaxSize value\r
+#\r
+# @retval 0     File is updated successfully.\r
+# @retval not 0 File is updated failed.\r
+#\r
+def PatchBinaryFile(FileName, ValueOffset, TypeName, ValueString, MaxSize=0):\r
+    #\r
+    # Length of Binary File\r
+    #\r
+    FileHandle = open(FileName, 'rb')\r
+    FileHandle.seek (0, 2)\r
+    FileLength = FileHandle.tell()\r
+    FileHandle.close()\r
+    #\r
+    # Unify string to upper string\r
+    #\r
+    TypeName = TypeName.upper()\r
+    #\r
+    # Get PCD value data length\r
+    #\r
+    ValueLength = 0\r
+    if TypeName == 'BOOLEAN':\r
+        ValueLength = 1\r
+    elif TypeName == 'UINT8':\r
+        ValueLength = 1\r
+    elif TypeName == 'UINT16':\r
+        ValueLength = 2\r
+    elif TypeName == 'UINT32':\r
+        ValueLength = 4\r
+    elif TypeName == 'UINT64':\r
+        ValueLength = 8\r
+    elif TypeName == 'VOID*':\r
+        if MaxSize == 0:\r
+            return OPTION_MISSING, "PcdMaxSize is not specified for VOID* type PCD."\r
+        ValueLength = int(MaxSize)\r
+    else:\r
+        return PARAMETER_INVALID, "PCD type %s is not valid." % (CommandOptions.PcdTypeName)\r
+    #\r
+    # Check PcdValue is in the input binary file.\r
+    #\r
+    if ValueOffset + ValueLength > FileLength:\r
+        return PARAMETER_INVALID, "PcdOffset + PcdMaxSize(DataType) is larger than the input file size."\r
+    #\r
+    # Read binary file into array\r
+    #\r
+    FileHandle = open(FileName, 'rb')\r
+    ByteArray = array.array('B')\r
+    ByteArray.fromfile(FileHandle, FileLength)\r
+    FileHandle.close()\r
+    OrigByteList = ByteArray.tolist()\r
+    ByteList = ByteArray.tolist()\r
+    #\r
+    # Clear the data in file\r
+    #\r
+    for Index in range(ValueLength):\r
+        ByteList[ValueOffset + Index] = 0\r
+    #\r
+    # Patch value into offset\r
+    #\r
+    SavedStr = ValueString\r
+    ValueString = ValueString.upper()\r
+    ValueNumber = 0\r
+    if TypeName == 'BOOLEAN':\r
+        #\r
+        # Get PCD value for BOOLEAN data type\r
+        #\r
+        try:\r
+            if ValueString == 'TRUE':\r
+                ValueNumber = 1\r
+            elif ValueString == 'FALSE':\r
+                ValueNumber = 0\r
+            elif ValueString.startswith('0X'):\r
+                ValueNumber = int (ValueString, 16)\r
+            else:\r
+                ValueNumber = int (ValueString)\r
+            if ValueNumber != 0:\r
+                ValueNumber = 1\r
+        except:\r
+            return PARAMETER_INVALID, "PCD Value %s is not valid dec or hex string." % (ValueString)\r
+        #\r
+        # Set PCD value into binary data\r
+        #\r
+        ByteList[ValueOffset] = ValueNumber\r
+    elif TypeName in ['UINT8', 'UINT16', 'UINT32', 'UINT64']:\r
+        #\r
+        # Get PCD value for UINT* data type\r
+        #\r
+        try:\r
+            if ValueString.startswith('0X'):\r
+                ValueNumber = int (ValueString, 16)\r
+            else:\r
+                ValueNumber = int (ValueString)\r
+        except:\r
+            return PARAMETER_INVALID, "PCD Value %s is not valid dec or hex string." % (ValueString)\r
+        #\r
+        # Set PCD value into binary data\r
+        #\r
+        for Index in range(ValueLength):\r
+            ByteList[ValueOffset + Index] = ValueNumber % 0x100\r
+            ValueNumber = ValueNumber / 0x100\r
+    elif TypeName == 'VOID*':\r
+        ValueString = SavedStr\r
+        if ValueString.startswith('L"'):\r
+            #\r
+            # Patch Unicode String\r
+            #\r
+            Index = 0\r
+            for ByteString in ValueString[2:-1]:\r
+                #\r
+                # Reserve zero as unicode tail\r
+                #\r
+                if Index + 2 >= ValueLength:\r
+                    break\r
+                #\r
+                # Set string value one by one\r
+                #\r
+                ByteList[ValueOffset + Index] = ord(ByteString)\r
+                Index = Index + 2\r
+        elif ValueString.startswith("{") and ValueString.endswith("}"):\r
+            #\r
+            # Patch {0x1, 0x2, ...} byte by byte\r
+            #\r
+            ValueList = ValueString[1 : len(ValueString) - 1].split(',')\r
+            Index = 0\r
+            try:\r
+                for ByteString in ValueList:\r
+                    ByteString = ByteString.strip()\r
+                    if ByteString.upper().startswith('0X'):\r
+                        ByteValue = int(ByteString, 16)\r
+                    else:\r
+                        ByteValue = int(ByteString)\r
+                    ByteList[ValueOffset + Index] = ByteValue % 0x100\r
+                    Index = Index + 1\r
+                    if Index >= ValueLength:\r
+                        break\r
+            except:\r
+                return PARAMETER_INVALID, "PCD Value %s is not valid dec or hex string array." % (ValueString)\r
+        else:\r
+            #\r
+            # Patch ascii string \r
+            #\r
+            Index = 0\r
+            for ByteString in ValueString[1:-1]:\r
+                #\r
+                # Reserve zero as string tail\r
+                #\r
+                if Index + 1 >= ValueLength:\r
+                    break\r
+                #\r
+                # Set string value one by one\r
+                #\r
+                ByteList[ValueOffset + Index] = ord(ByteString)\r
+                Index = Index + 1\r
+    #\r
+    # Update new data into input file.\r
+    #\r
+    if ByteList != OrigByteList:\r
+        ByteArray = array.array('B')\r
+        ByteArray.fromlist(ByteList)\r
+        FileHandle = open(FileName, 'wb')\r
+        ByteArray.tofile(FileHandle)\r
+        FileHandle.close()\r
+    return 0, "Patch Value into File %s successfully." % (FileName)\r
+\r
+## Parse command line options\r
+#\r
+# Using standard Python module optparse to parse command line option of this tool.\r
+#\r
+# @retval Options   A optparse.Values object containing the parsed options\r
+# @retval InputFile Path of file to be trimmed\r
+#\r
+def Options():\r
+    OptionList = [\r
+        make_option("-f", "--offset", dest="PcdOffset", action="store", type="int",\r
+                          help="Start offset to the image is used to store PCD value."),\r
+        make_option("-u", "--value", dest="PcdValue", action="store",\r
+                          help="PCD value will be updated into the image."),\r
+        make_option("-t", "--type", dest="PcdTypeName", action="store",\r
+                          help="The name of PCD data type may be one of VOID*,BOOLEAN, UINT8, UINT16, UINT32, UINT64."),\r
+        make_option("-s", "--maxsize", dest="PcdMaxSize", action="store", type="int",\r
+                          help="Max size of data buffer is taken by PCD value.It must be set when PCD type is VOID*."),\r
+        make_option("-v", "--verbose", dest="LogLevel", action="store_const", const=EdkLogger.VERBOSE,\r
+                          help="Run verbosely"),\r
+        make_option("-d", "--debug", dest="LogLevel", type="int",\r
+                          help="Run with debug information"),\r
+        make_option("-q", "--quiet", dest="LogLevel", action="store_const", const=EdkLogger.QUIET,\r
+                          help="Run quietly"),\r
+        make_option("-?", action="help", help="show this help message and exit"),\r
+    ]\r
+\r
+    # use clearer usage to override default usage message\r
+    UsageString = "%prog -f Offset -u Value -t Type [-s MaxSize] <input_file>"\r
+\r
+    Parser = OptionParser(description=__copyright__, version=__version__, option_list=OptionList, usage=UsageString)\r
+    Parser.set_defaults(LogLevel=EdkLogger.INFO)\r
+\r
+    Options, Args = Parser.parse_args()\r
+\r
+    # error check\r
+    if len(Args) == 0:\r
+        EdkLogger.error("PatchPcdValue", PARAMETER_INVALID, ExtraData=Parser.get_usage())\r
+\r
+    InputFile = Args[len(Args) - 1]\r
+    return Options, InputFile\r
+\r
+## Entrance method\r
+#\r
+# This method mainly dispatch specific methods per the command line options.\r
+# If no error found, return zero value so the caller of this tool can know\r
+# if it's executed successfully or not.\r
+#\r
+# @retval 0     Tool was successful\r
+# @retval 1     Tool failed\r
+#\r
+def Main():\r
+    try:\r
+        #\r
+        # Check input parameter\r
+        #\r
+        EdkLogger.Initialize()\r
+        CommandOptions, InputFile = Options()\r
+        if CommandOptions.LogLevel < EdkLogger.DEBUG_9:\r
+            EdkLogger.SetLevel(CommandOptions.LogLevel + 1)\r
+        else:\r
+            EdkLogger.SetLevel(CommandOptions.LogLevel)\r
+        if not os.path.exists (InputFile):\r
+            EdkLogger.error("PatchPcdValue", FILE_NOT_FOUND, ExtraData=InputFile)\r
+            return 1\r
+        if CommandOptions.PcdOffset == None or CommandOptions.PcdValue == None or CommandOptions.PcdTypeName == None:\r
+            EdkLogger.error("PatchPcdValue", OPTION_MISSING, ExtraData="PcdOffset or PcdValue of PcdTypeName is not specified.")\r
+            return 1\r
+        if CommandOptions.PcdTypeName.upper() not in ["BOOLEAN", "UINT8", "UINT16", "UINT32", "UINT64", "VOID*"]:\r
+            EdkLogger.error("PatchPcdValue", PARAMETER_INVALID, ExtraData="PCD type %s is not valid." % (CommandOptions.PcdTypeName))\r
+            return 1\r
+        if CommandOptions.PcdTypeName.upper() == "VOID*" and CommandOptions.PcdMaxSize == None:\r
+            EdkLogger.error("PatchPcdValue", OPTION_MISSING, ExtraData="PcdMaxSize is not specified for VOID* type PCD.")\r
+            return 1\r
+        #\r
+        # Patch value into binary image.\r
+        #\r
+        ReturnValue, ErrorInfo = PatchBinaryFile (InputFile, CommandOptions.PcdOffset, CommandOptions.PcdTypeName, CommandOptions.PcdValue, CommandOptions.PcdMaxSize)\r
+        if ReturnValue != 0:\r
+            EdkLogger.error("PatchPcdValue", ReturnValue, ExtraData=ErrorInfo)\r
+            return 1\r
+        return 0\r
+    except:\r
+        return 1\r
+\r
+if __name__ == '__main__':\r
+    r = Main()\r
+    sys.exit(r)\r