public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Eric Jin" <eric.jin@intel.com>
To: devel@edk2.groups.io
Cc: Bob Feng <bob.c.feng@intel.com>,
	Liming Gao <liming.gao@intel.com>,
	Kinney Michael D <michael.d.kinney@intel.com>
Subject: [PATCH v2 1/1] BaseTools/Capsule: Tool to Generate Windows Firmware Update Driver
Date: Mon,  3 Jun 2019 11:39:23 +0800	[thread overview]
Message-ID: <20190603033923.15280-1-eric.jin@intel.com> (raw)

https://bugzilla.tianocore.org/show_bug.cgi?id=1837

The tool is designed to generate Windows Firmware Update Drivers, the
input is one drivername.cap with related parameters, the output Windows
Driver package are composed by drivername.cap, drivername.inf and
drivername.cat to update the single payload in device.

usage:
GenerateWindowsDriver [-h] [--output-folder OUTPUTFOLDER]
                      [--product-fmp-guid PRODUCTFMPGUID]
                      [--capsuleversion-dotstring CAPSULEVERSION_DOTSTRING]
                      [--capsuleversion-hexstring CAPSULEVERSION_HEXSTRING]
                      [--product-fw-provider PRODUCTFWPROVIDER]
                      [--product-fw-mfg-name PRODUCTFWMFGNAME]
                      [--product-fw-desc PRODUCTFWDESC]
                      [--capsule-file-name CAPSULEFILENAME]
                      [--pfx-file PFXFILE] [--arch ARCH]
                      [--operating-system-string OPERATINGSYSTEMSTRING]

Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Kinney Michael D <michael.d.kinney@intel.com>
Signed-off-by: Eric Jin <eric.jin@intel.com>
---
 BaseTools/Source/Python/Capsule/CatGenerator.py                | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 BaseTools/Source/Python/Capsule/GenerateWindowsDriver.py       | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 BaseTools/Source/Python/Capsule/InfGenerator.py                | 210 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 BaseTools/Source/Python/Capsule/WindowsCapsuleSupportHelper.py | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 588 insertions(+)

diff --git a/BaseTools/Source/Python/Capsule/CatGenerator.py b/BaseTools/Source/Python/Capsule/CatGenerator.py
new file mode 100644
index 0000000000..77956d331d
--- /dev/null
+++ b/BaseTools/Source/Python/Capsule/CatGenerator.py
@@ -0,0 +1,161 @@
+## @file
+ # Script to generate Cat files for capsule update based on supplied inf file
+ #
+ # Copyright (c) 2019, Microsoft Corporation
+ # Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ # SPDX-License-Identifier: BSD-2-Clause-Patent
+ #
+ ##
+
+import os
+import logging
+import datetime
+import subprocess
+import threading
+
+class PropagatingThread(threading.Thread):
+    def run(self):
+        self.exc = None
+        try:
+            if hasattr(self, '_Thread__target'):
+                # Thread uses name mangling prior to Python 3.
+                self.ret = self._Thread__target(*self._Thread__args, **self._Thread__kwargs)
+            else:
+                self.ret = self._target(*self._args, **self._kwargs)
+        except BaseException as e:
+            self.exc = e
+    def join(self, timeout=None):
+        super(PropagatingThread, self).join()
+        if self.exc:
+             raise self.exc
+        return self.ret
+def reader(filepath, outstream, stream):
+    if filepath:
+        try:
+            with open(filepath, "w") as f:
+                print("The file is" + filepath)
+        except FileNotFoundError:
+            print("Sorry, the file" + filepath + "does not exist.")
+
+    while True:
+        s = stream.readline().decode()
+        if not s:
+            stream.close()
+            break
+        # write to file if caller provideds file
+        if filepath:
+            try:
+                with open(filepath, "a") as f:
+                    f.write(s)
+            except FileNotFoundError:
+                print("Sorry, the file" + filepath + "does not exist.")
+        if(outstream is not None):
+            # write to stream object if caller provided object
+            outstream.write(s)
+        logging.info(s.rstrip())
+
+def RunCmd(cmd, parameters, capture=True, workingdir=None, outfile=None, outstream=None, environ=None):
+    cmd = cmd.strip('"\'')
+    if " " in cmd:
+        cmd = '"' + cmd + '"'
+    if parameters is not None:
+        parameters = parameters.strip()
+        cmd += " " + parameters
+    starttime = datetime.datetime.now()
+    logging.info("Cmd to run is: " + cmd)
+    logging.info("------------------------------------------------")
+    logging.info("--------------Cmd Output Starting---------------")
+    logging.info("------------------------------------------------")
+    c = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=workingdir, shell=True, env=environ)
+    if(capture):
+        outr = PropagatingThread(target=reader, args=(outfile, outstream, c.stdout,))
+        outr.start()
+        outr.join()
+        c.wait()
+    else:
+        c.wait()
+
+    endtime = datetime.datetime.now()
+    delta = endtime - starttime
+    logging.info("------------------------------------------------")
+    logging.info("--------------Cmd Output Finished---------------")
+    logging.info("--------- Running Time (mm:ss): {0[0]:02}:{0[1]:02} ----------".format(divmod(delta.seconds, 60)))
+    logging.info("------------------------------------------------")
+    return c.returncode
+
+class CatGenerator(object):
+    SUPPORTED_OS = {'win10': '10',
+                    '10': '10',
+                    '10_au': '10_AU',
+                    '10_rs2': '10_RS2',
+                    '10_rs3': '10_RS3',
+                    '10_rs4': '10_RS4',
+                    'server10': 'Server10',
+                    'server2016': 'Server2016',
+                    'serverrs2': 'ServerRS2',
+                    'serverrs3': 'ServerRS3',
+                    'serverrs4': 'ServerRS4'
+                    }
+
+    def __init__(self, arch, os):
+        self.Arch = arch
+        self.OperatingSystem = os
+
+    @property
+    def Arch(self):
+        return self._arch
+
+    @Arch.setter
+    def Arch(self, value):
+        value = value.lower()
+        if(value == "x64") or (value == "amd64"):  # support amd64 value so INF and CAT tools can use same arch value
+            self._arch = "X64"
+        elif(value == "arm"):
+            self._arch = "ARM"
+        elif(value == "arm64") or (value == "aarch64"):  # support UEFI defined aarch64 value as well
+            self._arch = "ARM64"
+        else:
+            logging.critical("Unsupported Architecture: %s", value)
+            raise ValueError("Unsupported Architecture")
+
+    @property
+    def OperatingSystem(self):
+        return self._operatingsystem
+
+    @OperatingSystem.setter
+    def OperatingSystem(self, value):
+        key = value.lower()
+        if(key not in CatGenerator.SUPPORTED_OS.keys()):
+            logging.critical("Unsupported Operating System: %s", key)
+            raise ValueError("Unsupported Operating System")
+        self._operatingsystem = CatGenerator.SUPPORTED_OS[key]
+
+    def MakeCat(self, OutputCatFile, PathToInf2CatTool=None):
+        # Find Inf2Cat tool
+        if(PathToInf2CatTool is None):
+            PathToInf2CatTool = os.path.join(os.getenv("ProgramFiles(x86)"), "Windows Kits", "10",
+                                             "bin", "x86", "Inf2Cat.exe")
+            if not os.path.exists(PathToInf2CatTool):
+                logging.debug("Windows Kit 10 not Found....trying 8.1")
+                # Try 8.1 kit
+                PathToInf2CatTool.replace("10", "8.1")
+
+        # check if exists
+        if not os.path.exists(PathToInf2CatTool):
+            raise Exception("Can't find Inf2Cat on this machine.  Please install the Windows 10 WDK - "
+                            "https://developer.microsoft.com/en-us/windows/hardware/windows-driver-kit")
+
+        # Adjust for spaces in the path (when calling the command).
+        if " " in PathToInf2CatTool:
+            PathToInf2CatTool = '"' + PathToInf2CatTool + '"'
+
+        OutputFolder = os.path.dirname(OutputCatFile)
+        # Make Cat file
+        cmd = "/driver:. /os:" + self.OperatingSystem + "_" + self.Arch + " /verbose"
+        ret = RunCmd(PathToInf2CatTool, cmd, workingdir=OutputFolder)
+        if(ret != 0):
+            raise Exception("Creating Cat file Failed with errorcode %d" % ret)
+        if(not os.path.isfile(OutputCatFile)):
+            raise Exception("CAT file (%s) not created" % OutputCatFile)
+
+        return 0
diff --git a/BaseTools/Source/Python/Capsule/GenerateWindowsDriver.py b/BaseTools/Source/Python/Capsule/GenerateWindowsDriver.py
new file mode 100644
index 0000000000..1d543b3fca
--- /dev/null
+++ b/BaseTools/Source/Python/Capsule/GenerateWindowsDriver.py
@@ -0,0 +1,115 @@
+## @file
+# Generate a capsule windows driver.
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+'''
+GenerateWindowsDriver
+'''
+
+import sys
+import argparse
+import uuid
+import struct
+import subprocess
+import os
+import tempfile
+import shutil
+import platform
+import re
+import logging
+from WindowsCapsuleSupportHelper import WindowsCapsuleSupportHelper
+
+#
+# Globals for help information
+#
+__prog__        = 'GenerateWindowsDriver'
+__version__     = '0.0'
+__copyright__   = 'Copyright (c) 2019, Intel Corporation. All rights reserved.'
+__description__ = 'Generate Capsule Windows Driver.\n'
+
+
+if __name__ == '__main__':
+    def convert_arg_line_to_args(arg_line):
+        for arg in arg_line.split():
+            if not arg.strip():
+                continue
+            yield arg
+
+    parser = argparse.ArgumentParser (
+                        prog = __prog__,
+                        description = __description__ + __copyright__,
+                        conflict_handler = 'resolve',
+                        fromfile_prefix_chars = '@'
+                        )
+    parser.convert_arg_line_to_args = convert_arg_line_to_args
+    parser.add_argument("--output-folder", dest = 'OutputFolder', help = "firmware resource update driver package output folder.")
+    parser.add_argument("--product-fmp-guid", dest = 'ProductFmpGuid', help = "firmware GUID of resource update driver package")
+    parser.add_argument("--capsuleversion-dotstring", dest = 'CapsuleVersion_DotString', help = "firmware version with date on which update driver package is authored")
+    parser.add_argument("--capsuleversion-hexstring", dest = 'CapsuleVersion_HexString', help = "firmware version in Hex of update driver package")
+    parser.add_argument("--product-fw-provider", dest = 'ProductFwProvider', help = "vendor/provider of entire firmware resource update driver package")
+    parser.add_argument("--product-fw-mfg-name", dest = 'ProductFwMfgName', help = "manufacturer/vendor of firmware resource update driver package")
+    parser.add_argument("--product-fw-desc", dest = "ProductFwDesc", help = "description about resource update driver")
+    parser.add_argument("--capsule-file-name", dest = 'CapsuleFileName', help ="firmware resource image file")
+    parser.add_argument("--pfx-file", dest = 'PfxFile', help = "pfx file path used to sign resource update driver")
+    parser.add_argument("--arch", dest = 'Arch', help = "supported architecture:arm/x64/amd64/arm64/aarch64", default = 'amd64')
+    parser.add_argument("--operating-system-string", dest = 'OperatingSystemString', help = "supported operating system:win10/10/10_au/10_rs2/10_rs3/10_rs4/server10/server2016/serverrs2/serverrs3/serverrs4", default = "win10")
+
+    def ArgCheck(args):
+        Version = args.CapsuleVersion_DotString.split('.')
+
+        if len(Version) != 4:
+            logging.critical("Name invalid: '%s'", args.CapsuleVersion_DotString)
+            raise ValueError("Name invalid.")
+        for sub in Version:
+            if  int(sub) > 65536:
+                logging.critical("Name invalid: '%s'", args.CapsuleVersion_DotString)
+                raise ValueError("Name exceed limit 65536.")
+
+        if not (re.compile(r'[0-9.]*$')).match(args.CapsuleVersion_DotString):
+            logging.critical("Name invalid: '%s'", args.CapsuleVersion_DotString)
+            raise ValueError("Name has invalid chars.")
+
+    def CapsuleGuidCheck(InputFile, Guid):
+        TempCapDecode = 'TempCapDecode.txt'
+        Command = 'python GenerateCapsule.py "' + InputFile + '" --dump-info >' + TempCapDecode
+        os.system (Command)
+        with open(TempCapDecode, 'rb') as f:
+            for line in f:
+                if re.search(b'UpdateImageTypeId', line, re.M|re.I):
+                    CapGuid = str(line).split('= ')[1][:-5]
+                    break
+            f.close()
+            os.remove(TempCapDecode)
+            if (Guid != CapGuid):
+                print('GenerateWindowsDriver error: Different Guid from Capsule')
+                sys.exit(1)
+
+    args = parser.parse_args()
+
+    InputFile = os.path.join(args.OutputFolder, '') + args.CapsuleFileName
+
+    ProductName = args.CapsuleFileName.strip('.cap')
+    WindowsDriver = WindowsCapsuleSupportHelper ()
+
+    ArgCheck(args)
+    CapsuleGuidCheck(InputFile, args.ProductFmpGuid)
+
+    WindowsDriver.PackageWindowsCapsuleFiles (
+                                                   args.OutputFolder,
+                                                   ProductName,
+                                                   args.ProductFmpGuid,
+                                                   args.CapsuleVersion_DotString,
+                                                   args.CapsuleVersion_HexString,
+                                                   args.ProductFwProvider,
+                                                   args.ProductFwMfgName,
+                                                   args.ProductFwDesc,
+                                                   args.CapsuleFileName,
+                                                   args.PfxFile,
+                                                   None,
+                                                   None,
+                                                   args.Arch,
+                                                   args.OperatingSystemString
+                                                   )
diff --git a/BaseTools/Source/Python/Capsule/InfGenerator.py b/BaseTools/Source/Python/Capsule/InfGenerator.py
new file mode 100644
index 0000000000..508bbed0ef
--- /dev/null
+++ b/BaseTools/Source/Python/Capsule/InfGenerator.py
@@ -0,0 +1,210 @@
+## @file
+ # Script to generate inf files for capsule update based on INF TEMPLATE and
+ # supplied information (Name, Version, ESRT Guid, Rollback, etc.)
+ #
+ # Copyright (c) 2019, Microsoft Corporation
+ # Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ # SPDX-License-Identifier: BSD-2-Clause-Patent
+ ##
+
+import os
+import logging
+import datetime
+import re
+import uuid
+
+
+#####
+#
+#####
+class InfGenerator(object):
+
+    ### INF Template ###
+    TEMPLATE = r""";
+; {Name}.inf
+; {DriverVersion}
+; Copyright (C) 2019 Microsoft Corporation.  All Rights Reserved.
+;
+[Version]
+Signature="$WINDOWS NT$"
+Class=Firmware
+ClassGuid={{f2e7dd72-6468-4e36-b6f1-6488f42c1b52}}
+Provider=%Provider%
+DriverVer={Date},{DriverVersion}
+PnpLockdown=1
+CatalogFile={Name}.cat
+[Manufacturer]
+%MfgName% = Firmware,NT{Arch}
+[Firmware.NT{Arch}]
+%FirmwareDesc% = Firmware_Install,UEFI\RES_{{{EsrtGuid}}}
+[Firmware_Install.NT]
+CopyFiles = Firmware_CopyFiles
+{Rollback}
+[Firmware_CopyFiles]
+{FirmwareBinFile}
+[Firmware_Install.NT.Hw]
+AddReg = Firmware_AddReg
+[Firmware_AddReg]
+HKR,,FirmwareId,,{{{EsrtGuid}}}
+HKR,,FirmwareVersion,%REG_DWORD%,{VersionHexString}
+HKR,,FirmwareFilename,,{FirmwareBinFile}
+[SourceDisksNames]
+1 = %DiskName%
+[SourceDisksFiles]
+{FirmwareBinFile} = 1
+[DestinationDirs]
+DefaultDestDir = %DIRID_WINDOWS%,Firmware ; %SystemRoot%\Firmware
+[Strings]
+; localizable
+Provider     = "{Provider}"
+MfgName      = "{MfgName}"
+FirmwareDesc = "{Description}"
+DiskName     = "Firmware Update"
+; non-localizable
+DIRID_WINDOWS = 10
+REG_DWORD     = 0x00010001
+"""
+
+    ROLLBACKTEMPLATE = r"""AddReg    = Firmware_DowngradePolicy_Addreg
+  ;override firmware resource update policy to allow downgrade to lower version
+  [Firmware_DowngradePolicy_Addreg]
+  HKLM,SYSTEM\CurrentControlSet\Control\FirmwareResources\{{{EsrtGuid}}},Policy,%REG_DWORD%,1
+  """
+
+    SUPPORTED_ARCH = {'amd64': 'amd64',
+                      'x64': 'amd64',
+                      'arm': 'arm',
+                      'arm64': 'ARM64',
+                      'aarch64': 'ARM64'
+                      }
+
+    def __init__(self, name_string, provider, esrt_guid, arch, description_string, version_string, version_hex):
+        self.Name = name_string
+        self.Provider = provider
+        self.EsrtGuid = esrt_guid
+        self.Arch = arch
+        self.Description = description_string
+        self.VersionString = version_string
+        self.VersionHex = version_hex
+        self._manufacturer = None  # default for optional feature
+        self._date = datetime.date.today()
+
+    @property
+    def Name(self):
+        return self._name
+
+    @Name.setter
+    def Name(self, value):
+        # test here for invalid chars
+        if not (re.compile(r'[\w-]*$')).match(value):
+            logging.critical("Name invalid: '%s'", value)
+            raise ValueError("Name has invalid chars.")
+        self._name = value
+
+    @property
+    def Provider(self):
+        return self._provider
+
+    @Provider.setter
+    def Provider(self, value):
+        self._provider = value
+
+    @property
+    def Manufacturer(self):
+        if(self._manufacturer is None):
+            return self.Provider
+
+        return self._manufacturer
+
+    @Manufacturer.setter
+    def Manufacturer(self, value):
+        self._manufacturer = value
+
+    @property
+    def Description(self):
+        return self._description
+
+    @Description.setter
+    def Description(self, value):
+        self._description = value
+
+    @property
+    def EsrtGuid(self):
+        return self._esrtguid
+
+    @EsrtGuid.setter
+    def EsrtGuid(self, value):
+        uuid.UUID(value)  # if this works it is valid...otherwise throws exception
+        # todo - make sure it is formatted exactly right
+        self._esrtguid = value
+
+    @property
+    def VersionString(self):
+        return self._versionstring
+
+    @VersionString.setter
+    def VersionString(self, value):
+        c = value.count(".")
+        if(c < 1) or (c > 3):
+            logging.critical("Version string in invalid format.")
+            raise ValueError("VersionString must be in format of xx.xx -> xx.xx.xx.xx")
+        self._versionstring = value
+
+    @property
+    def VersionHex(self):
+        return "0x%08X" % self._versionhex
+
+    @VersionHex.setter
+    def VersionHex(self, value):
+        a = int(value, 0)
+        if(a > 0xFFFFFFFF):
+            logging.critical("VersionHex invalid: '%s'", value)
+            raise ValueError("VersionHex must fit within 32bit value range for unsigned integer")
+        self._versionhex = a
+
+    @property
+    def Arch(self):
+        return self._arch
+
+    @Arch.setter
+    def Arch(self, value):
+        key = value.lower()
+        if(key not in InfGenerator.SUPPORTED_ARCH.keys()):
+            logging.critical("Arch invalid: '%s'", value)
+            raise ValueError("Unsupported Architecture")
+        self._arch = InfGenerator.SUPPORTED_ARCH[key]
+
+    @property
+    def Date(self):
+        return self._date.strftime("%m/%d/%Y")
+
+    @Date.setter
+    def Date(self, value):
+        if(not isinstance(value, datetime.date)):
+            raise ValueError("Date must be a datetime.date object")
+        self._date = value
+
+    def MakeInf(self, OutputInfFilePath, FirmwareBinFileName, Rollback=False):
+        RollbackString = ""
+        if(Rollback):
+            RollbackString = InfGenerator.ROLLBACKTEMPLATE.format(EsrtGuid=self.EsrtGuid)
+
+        binfilename = os.path.basename(FirmwareBinFileName)
+
+        Content = InfGenerator.TEMPLATE.format(
+            Name=self.Name,
+            Date=self.Date,
+            Arch=self.Arch,
+            DriverVersion=self.VersionString,
+            EsrtGuid=self.EsrtGuid,
+            FirmwareBinFile=binfilename,
+            VersionHexString=self.VersionHex,
+            Provider=self.Provider,
+            MfgName=self.Manufacturer,
+            Description=self.Description,
+            Rollback=RollbackString)
+
+        with open(OutputInfFilePath, "w") as f:
+            f.write(Content)
+
+        return 0
diff --git a/BaseTools/Source/Python/Capsule/WindowsCapsuleSupportHelper.py b/BaseTools/Source/Python/Capsule/WindowsCapsuleSupportHelper.py
new file mode 100644
index 0000000000..8abac3e31d
--- /dev/null
+++ b/BaseTools/Source/Python/Capsule/WindowsCapsuleSupportHelper.py
@@ -0,0 +1,102 @@
+##
+# UefiBuild Plugin that supports Window Capsule files based on the
+# Windows Firmware Update Platform spec.
+# Creates INF, Cat, and then signs it
+#
+#
+# Copyright (c) 2018, Microsoft Corporation
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+import sys
+import re
+import datetime
+import os
+import logging
+from CatGenerator import CatGenerator
+from InfGenerator import InfGenerator
+from CatGenerator import RunCmd
+
+def CatalogSignWithSignTool(SignToolPath, ToSignFilePath, PfxFilePath, PfxPass=None):
+    # check signtool path
+    if not os.path.exists(SignToolPath):
+        logging.error("Path to signtool invalid.  %s" % SignToolPath)
+        return -1
+
+    # Adjust for spaces in the path (when calling the command).
+    if " " in SignToolPath:
+        SignToolPath = '"' + SignToolPath + '"'
+
+    OutputDir = os.path.dirname(ToSignFilePath)
+    # Signtool docs https://docs.microsoft.com/en-us/dotnet/framework/tools/signtool-exe
+    # todo: link to catalog signing documentation
+    params = "sign /a /fd SHA256 /f " + PfxFilePath
+    if PfxPass is not None:
+        # add password if set
+        params = params + ' /p ' + PfxPass
+    params = params + ' /debug /v "' + ToSignFilePath + '" '
+    ret = RunCmd(SignToolPath, params, workingdir=OutputDir)
+    if(ret != 0):
+        logging.error("Signtool failed %d" % ret)
+    return ret
+
+class WindowsCapsuleSupportHelper(object):
+    @staticmethod
+    def _LocateLatestWindowsKits():
+        result = None
+
+        # Start with a base path and use it to start locating the ideal directory.
+        base_path = os.path.join(os.getenv("ProgramFiles(x86)"), "Windows Kits")
+
+        # Check for Win 10 kits first.
+        base_10_path = os.path.join(base_path, "10", "bin")
+        if os.path.isdir(base_10_path):
+            # If you can find one of the new kit paths, use it.
+            # Walk backwards to test the most recent kit first.
+            for sub_path in reversed(os.listdir(base_10_path)):
+                if sub_path.startswith("10.") and os.path.isdir(os.path.join(base_10_path, sub_path, "x64")):
+                    result = os.path.join(base_10_path, sub_path, "x64")
+                    break
+
+            # Otherwise, fall back to the legacy path.
+            if not result and os.path.isdir(os.path.join(base_10_path, "x64")):
+                result = os.path.join(base_10_path, "x64")
+        # If not, fall back to Win 8.1.
+        elif os.path.isdir(os.path.join(base_path, "8.1", "bin", "x64")):
+            result = os.path.join(base_path, "8.1", "bin", "x64")
+        return result
+
+    def RegisterHelpers(self, obj):
+        fp = os.path.abspath(__file__)
+        obj.Register("PackageWindowsCapsuleFiles", WindowsCapsuleSupportHelper.PackageWindowsCapsuleFiles, fp)
+
+
+    @staticmethod
+    def PackageWindowsCapsuleFiles(OutputFolder, ProductName, ProductFmpGuid, CapsuleVersion_DotString,CapsuleVersion_HexString, ProductFwProvider, ProductFwMfgName, ProductFwDesc, CapsuleFileName, PfxFile=None, PfxPass=None, Rollback=False, Arch='amd64', OperatingSystem_String='Win10'):
+        logging.debug("CapsulePackage: Create Windows Capsule Files")
+        #Make INF
+        InfFilePath = os.path.join(OutputFolder, ProductName + ".inf")
+        InfTool = InfGenerator(ProductName, ProductFwProvider, ProductFmpGuid, Arch, ProductFwDesc, CapsuleVersion_DotString, CapsuleVersion_HexString)
+        InfTool.Manufacturer = ProductFwMfgName #optional
+        ret = InfTool.MakeInf(InfFilePath, CapsuleFileName, Rollback)
+        if(ret != 0):
+            raise Exception("CreateWindowsInf Failed with errorcode %d" % ret)
+        #Make CAT
+        CatFilePath = os.path.realpath(os.path.join(OutputFolder, ProductName + ".cat"))
+        CatTool = CatGenerator(Arch, OperatingSystem_String)
+        ret = CatTool.MakeCat(CatFilePath)
+
+        if(ret != 0):
+            raise Exception("Creating Cat file Failed with errorcode %d" % ret)
+        if(PfxFile is not None):
+            #Find Signtool
+            WinKitsPath = WindowsCapsuleSupportHelper._LocateLatestWindowsKits()
+            SignToolPath = os.path.join(WinKitsPath, "signtool.exe")
+            if not os.path.exists(SignToolPath):
+                raise Exception("Can't find signtool on this machine.")
+            #dev sign the cat file
+            ret = CatalogSignWithSignTool(SignToolPath, CatFilePath, PfxFile, PfxPass)
+            if(ret != 0):
+                raise Exception("Signing Cat file Failed with errorcode %d" % ret)
+        return ret
-- 
2.20.1.windows.1


             reply	other threads:[~2019-06-03  3:39 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-03  3:39 Eric Jin [this message]
2019-06-11  1:36 ` [PATCH v2 1/1] BaseTools/Capsule: Tool to Generate Windows Firmware Update Driver Bob Feng
2019-06-11  2:10   ` Eric Jin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190603033923.15280-1-eric.jin@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox