Home | History | Annotate | Download | only in Xml
      1 ## @file

      2 # This file is used to parse a xml file of .PKG file

      3 #

      4 # Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>

      5 #

      6 # This program and the accompanying materials are licensed and made available 

      7 # under the terms and conditions of the BSD License which accompanies this 

      8 # distribution. The full text of the license may be found at 

      9 # http://opensource.org/licenses/bsd-license.php

     10 #

     11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

     12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

     13 #

     14 
     15 '''
     16 XmlParser
     17 '''
     18 
     19 ##

     20 # Import Modules

     21 #

     22 import re
     23 
     24 from Library.Xml.XmlRoutines import XmlNode
     25 from Library.Xml.XmlRoutines import CreateXmlElement
     26 from Library.Xml.XmlRoutines import XmlList
     27 from Library.Xml.XmlRoutines import XmlParseFile
     28 from Core.DistributionPackageClass import DistributionPackageClass
     29 from Object.POM.ModuleObject import DepexObject
     30 from Library.ParserValidate import IsValidInfMoudleType
     31 from Library.ParserValidate import IsValidInstallPath
     32 from Library.Misc import IsEqualList
     33 from Library.Misc import Sdict
     34 
     35 from Logger.StringTable import ERR_XML_INVALID_VARIABLENAME
     36 from Logger.StringTable import ERR_XML_INVALID_LIB_SUPMODLIST
     37 from Logger.StringTable import ERR_XML_INVALID_EXTERN_SUPARCHLIST
     38 from Logger.StringTable import ERR_XML_INVALID_EXTERN_SUPMODLIST
     39 from Logger.StringTable import ERR_XML_INVALID_EXTERN_SUPMODLIST_NOT_LIB
     40 from Logger.StringTable import ERR_FILE_NAME_INVALIDE
     41 from Logger.ToolError import PARSER_ERROR
     42 from Logger.ToolError import FORMAT_INVALID
     43 
     44 from Xml.CommonXml import DistributionPackageHeaderXml
     45 from Xml.CommonXml import MiscellaneousFileXml
     46 from Xml.CommonXml import UserExtensionsXml
     47 from Xml.XmlParserMisc import ConvertVariableName
     48 from Xml.XmlParserMisc import IsRequiredItemListNull
     49 from Xml.ModuleSurfaceAreaXml import ModuleSurfaceAreaXml
     50 from Xml.PackageSurfaceAreaXml import PackageSurfaceAreaXml
     51 
     52 import Logger.Log as Logger
     53 
     54 ##

     55 # DistributionPackageXml

     56 #

     57 class DistributionPackageXml(object):
     58     def __init__(self):
     59         self.DistP = DistributionPackageClass()
     60         self.Pkg = ''
     61 
     62     ## ValidateDistributionPackage

     63     #

     64     # Check if any required item is missing in DistributionPackage

     65     #

     66     def ValidateDistributionPackage(self):
     67         XmlTreeLevel = ['DistributionPackage']
     68         if self.DistP:
     69             #

     70             # Check DistributionPackage -> DistributionHeader

     71             #

     72             XmlTreeLevel = ['DistributionPackage', '']
     73             CheckDict = {'DistributionHeader':self.DistP.Header }
     74             IsRequiredItemListNull(CheckDict, XmlTreeLevel)
     75 
     76             if self.DistP.Header:
     77                 DpHeader = self.DistP.Header
     78                 XmlTreeLevel = ['DistributionPackage', 'DistributionHeader']
     79                 CheckDict = Sdict()
     80                 if DpHeader.GetAbstract():
     81                     DPAbstract = DpHeader.GetAbstract()[0][1]
     82                 else:
     83                     DPAbstract = ''
     84                 if DpHeader.GetCopyright():
     85                     DPCopyright = DpHeader.GetCopyright()[0][1]
     86                 else:
     87                     DPCopyright = ''
     88                 if DpHeader.GetLicense():
     89                     DPLicense = DpHeader.GetLicense()[0][1]
     90                 else:
     91                     DPLicense = ''
     92                 
     93                 CheckDict['Name'] = DpHeader.GetName()
     94                 CheckDict['GUID'] = DpHeader.GetGuid()
     95                 CheckDict['Version'] = DpHeader.GetVersion()
     96                 CheckDict['Copyright'] = DPCopyright
     97                 CheckDict['License'] = DPLicense
     98                 CheckDict['Abstract'] = DPAbstract
     99                 CheckDict['Vendor'] = DpHeader.GetVendor()
    100                 CheckDict['Date'] = DpHeader.GetDate()
    101                 CheckDict['XmlSpecification'] = DpHeader.GetXmlSpecification()
    102 
    103                 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    104             else:
    105                 XmlTreeLevel = ['DistributionPackage', 'DistributionHeader']
    106                 CheckDict = CheckDict = {'DistributionHeader':'', }
    107                 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    108 
    109             #

    110             # Check Each Package

    111             #

    112             for Key in self.DistP.PackageSurfaceArea:
    113                 ValidatePackageSurfaceArea(self.DistP.PackageSurfaceArea[Key])
    114 
    115             #

    116             # Check Each Module

    117             #

    118             for Key in self.DistP.ModuleSurfaceArea:
    119                 ValidateMS(self.DistP.ModuleSurfaceArea[Key], ['DistributionPackage', 'ModuleSurfaceArea'])
    120 
    121             #

    122             # Check Each Tool   

    123             #

    124             if self.DistP.Tools:
    125                 XmlTreeLevel = ['DistributionPackage', 'Tools', 'Header']
    126                 CheckDict = {'Name':self.DistP.Tools.GetName(), }
    127                 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    128 
    129                 if not self.DistP.Tools.GetFileList():
    130                     XmlTreeLevel = ['DistributionPackage', 'Tools']
    131                     CheckDict = {'FileName':None, }
    132                     IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    133                 for Item in self.DistP.Tools.GetFileList():
    134                     XmlTreeLevel = ['DistributionPackage', 'Tools']
    135                     CheckDict = {'FileName':Item.GetURI(), }
    136                     IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    137 
    138             #

    139             # Check Each Misc File

    140             #

    141             if self.DistP.MiscellaneousFiles:
    142                 XmlTreeLevel = ['DistributionPackage', 'MiscellaneousFiles', 'Header']
    143                 CheckDict = {'Name':self.DistP.MiscellaneousFiles.GetName(), }
    144                 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    145 
    146                 if not self.DistP.MiscellaneousFiles.GetFileList():
    147                     XmlTreeLevel = ['DistributionPackage', 'MiscellaneousFiles']
    148                     CheckDict = {'FileName':None, }
    149                     IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    150                 for Item in self.DistP.MiscellaneousFiles.GetFileList():
    151                     XmlTreeLevel = ['DistributionPackage', 'MiscellaneousFiles']
    152                     CheckDict = {'FileName':Item.GetURI(), }
    153                     IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    154 
    155             #

    156             # Check Each Distribution Level User Extension

    157             #

    158             for Item in self.DistP.UserExtensions:
    159                 XmlTreeLevel = ['DistributionPackage', 'UserExtensions']
    160                 CheckDict = {'UserId':Item.GetUserID(), }
    161                 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    162 
    163 
    164     def FromXml(self, Filename=None):
    165         if Filename != None:
    166             self.DistP = DistributionPackageClass()
    167             #

    168             # Load to XML

    169             #

    170             self.Pkg = XmlParseFile(Filename)
    171 
    172             #

    173             # Parse Header information

    174             #

    175             Tmp = DistributionPackageHeaderXml()
    176             DistributionPackageHeader = \
    177             Tmp.FromXml(XmlNode(self.Pkg, '/DistributionPackage/DistributionHeader'), 'DistributionHeader')
    178             self.DistP.Header = DistributionPackageHeader
    179             #

    180             # Parse each PackageSurfaceArea

    181             #

    182             for Item in XmlList(self.Pkg, '/DistributionPackage/PackageSurfaceArea'):
    183                 Psa = PackageSurfaceAreaXml()
    184                 Package = Psa.FromXml(Item, 'PackageSurfaceArea')
    185                 self.DistP.PackageSurfaceArea[(Package.GetGuid(), \
    186                                                Package.GetVersion(), \
    187                                                Package.GetPackagePath())] = \
    188                                                Package
    189             #

    190             # Parse each ModuleSurfaceArea

    191             #

    192             for Item in XmlList(self.Pkg, '/DistributionPackage/ModuleSurfaceArea'):
    193                 Msa = ModuleSurfaceAreaXml()
    194                 Module = Msa.FromXml(Item, 'ModuleSurfaceArea', True)
    195                 ModuleKey = (Module.GetGuid(), Module.GetVersion(), Module.GetName(), Module.GetModulePath())
    196                 self.DistP.ModuleSurfaceArea[ModuleKey] = Module
    197 
    198             #    

    199             # Parse Tools

    200             #

    201             Tmp = MiscellaneousFileXml()
    202             self.DistP.Tools = Tmp.FromXml2(XmlNode(self.Pkg, '/DistributionPackage/Tools'), 'Tools')
    203 
    204             #

    205             # Parse MiscFiles

    206             #

    207             Tmp = MiscellaneousFileXml()
    208             self.DistP.MiscellaneousFiles = \
    209             Tmp.FromXml2(XmlNode(self.Pkg, \
    210                                  '/DistributionPackage/MiscellaneousFiles'), \
    211                                  'MiscellaneousFiles')
    212 
    213             #

    214             # Parse UserExtensions

    215             #

    216             for Item in XmlList(self.Pkg, '/DistributionPackage/UserExtensions'):
    217                 Tmp = UserExtensionsXml()
    218                 self.DistP.UserExtensions.append(Tmp.FromXml2(Item, 'UserExtensions'))
    219 
    220             #

    221             # Check Required Items for XML

    222             #

    223             self.ValidateDistributionPackage()
    224 
    225             return self.DistP
    226 
    227     def ToXml(self, DistP):
    228         if self.DistP:
    229             pass
    230         if DistP != None:
    231             #

    232             # Parse DistributionPackageHeader

    233             #

    234             Attrs = [['xmlns', 'http://www.uefi.org/2011/1.1'],
    235                      ['xmlns:xsi', 'http:/www.w3.org/2001/XMLSchema-instance'],
    236                      ]
    237             Root = CreateXmlElement('DistributionPackage', '', [], Attrs)
    238 
    239             Tmp = DistributionPackageHeaderXml()
    240             Root.appendChild(Tmp.ToXml(DistP.Header, 'DistributionHeader'))
    241             #

    242             # Parse each PackageSurfaceArea

    243             #

    244             for Package in DistP.PackageSurfaceArea.values():
    245                 Psa = PackageSurfaceAreaXml()
    246                 DomPackage = Psa.ToXml(Package)
    247                 Root.appendChild(DomPackage)
    248             #

    249             # Parse each ModuleSurfaceArea

    250             #

    251             for Module in DistP.ModuleSurfaceArea.values():
    252                 Msa = ModuleSurfaceAreaXml()
    253                 DomModule = Msa.ToXml(Module)
    254                 Root.appendChild(DomModule)
    255             #    

    256             # Parse Tools

    257             #

    258             Tmp = MiscellaneousFileXml()
    259             ToolNode = Tmp.ToXml2(DistP.Tools, 'Tools')
    260             if ToolNode is not None:
    261                 Root.appendChild(ToolNode)
    262             #

    263             # Parse MiscFiles

    264             #

    265             Tmp = MiscellaneousFileXml()
    266             MiscFileNode = Tmp.ToXml2(DistP.MiscellaneousFiles,
    267                                       'MiscellaneousFiles')
    268             if MiscFileNode is not None:
    269                 Root.appendChild(MiscFileNode)
    270 
    271             XmlContent = Root.toprettyxml(indent='  ')
    272 
    273 
    274             #

    275             # Remove empty element

    276             #

    277             XmlContent = re.sub(r'[\s\r\n]*<[^<>=]*/>', '', XmlContent)
    278 
    279             #

    280             # Remove empty help text element

    281             #

    282             XmlContent = re.sub(r'[\s\r\n]*<HelpText Lang="en-US"/>', '',
    283                                 XmlContent)
    284 
    285             #

    286             # Remove SupArchList="COMMON" or "common"

    287             #

    288             XmlContent = \
    289             re.sub(r'[\s\r\n]*SupArchList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*COMMON'
    290             '[\s\r\n]*"', '', XmlContent)
    291             XmlContent = \
    292             re.sub(r'[\s\r\n]*SupArchList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*common'
    293             '[\s\r\n]*"', '', XmlContent)
    294             #

    295             # Remove <SupArchList> COMMON </SupArchList>

    296             #

    297             XmlContent = \
    298             re.sub(r'[\s\r\n]*<SupArchList>[\s\r\n]*COMMON[\s\r\n]*'
    299             '</SupArchList>[\s\r\n]*', '', XmlContent)
    300 
    301             #

    302             # Remove <SupArchList> common </SupArchList>

    303             #

    304             XmlContent = \
    305             re.sub(r'[\s\r\n]*<SupArchList>[\s\r\n]*'
    306             'common[\s\r\n]*</SupArchList>[\s\r\n]*', '', XmlContent)
    307 
    308             #

    309             # Remove SupModList="COMMON" or "common"

    310             #            

    311             XmlContent = \
    312             re.sub(r'[\s\r\n]*SupModList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*COMMON'
    313             '[\s\r\n]*"', '', XmlContent)
    314             XmlContent = \
    315             re.sub(r'[\s\r\n]*SupModList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*common'
    316             '[\s\r\n]*"', '', XmlContent)
    317 
    318             return XmlContent
    319 
    320         return ''
    321 
    322 ## ValidateMS

    323 #

    324 # Check if any required item is missing in ModuleSurfaceArea

    325 #

    326 # @param Module: The ModuleSurfaceArea to be checked

    327 # @param XmlTreeLevel: The top level of Module 

    328 #

    329 def ValidateMS(Module, TopXmlTreeLevel):
    330     ValidateMS1(Module, TopXmlTreeLevel)
    331     ValidateMS2(Module, TopXmlTreeLevel)
    332     ValidateMS3(Module, TopXmlTreeLevel)
    333 
    334 ## ValidateMS1

    335 #

    336 # Check if any required item is missing in ModuleSurfaceArea

    337 #

    338 # @param Module: The ModuleSurfaceArea to be checked

    339 # @param XmlTreeLevel: The top level of Module 

    340 #

    341 def ValidateMS1(Module, TopXmlTreeLevel):
    342     #

    343     # Check Guids -> GuidCName

    344     #

    345     XmlTreeLevel = TopXmlTreeLevel + ['Guids']
    346     for Item in Module.GetGuidList():
    347         if Item == None:
    348             CheckDict = {'GuidCName':''}
    349             IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    350 
    351     XmlTreeLevel = TopXmlTreeLevel + ['Guids', 'GuidCName']
    352     for Item in Module.GetGuidList():
    353         CheckDict = {'CName':Item.GetCName(),
    354                      'GuidType':Item.GetGuidTypeList(),
    355                      'Usage':Item.GetUsage()}
    356         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    357 
    358         if Item.GetVariableName():
    359             Result = ConvertVariableName(Item.GetVariableName())
    360             if Result is None:
    361                 Msg = "->".join(Node for Node in XmlTreeLevel)
    362                 ErrorMsg = ERR_XML_INVALID_VARIABLENAME % (Item.GetVariableName(), Item.GetCName(), Msg)
    363                 Logger.Error('\nUPT', PARSER_ERROR, ErrorMsg, RaiseError=True)
    364             else:
    365                 Item.SetVariableName(Result)
    366 
    367     #

    368     # Check Protocols -> Protocol

    369     #

    370     XmlTreeLevel = TopXmlTreeLevel + ['Protocols']
    371     for Item in Module.GetProtocolList():
    372         if Item == None:
    373             CheckDict = {'Protocol':''}
    374             IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    375 
    376     XmlTreeLevel = TopXmlTreeLevel + ['Protocols', 'Protocol']
    377     for Item in Module.GetProtocolList():
    378         CheckDict = {'CName':Item.GetCName(),
    379                      'Usage':Item.GetUsage()}
    380         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    381 
    382     #

    383     # Check PPIs -> Ppi

    384     #

    385     XmlTreeLevel = TopXmlTreeLevel + ['PPIs']
    386     for Item in Module.GetPpiList():
    387         if Item == None:
    388             CheckDict = {'Ppi':''}
    389             IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    390 
    391     XmlTreeLevel = TopXmlTreeLevel + ['PPIs', 'Ppi']
    392     for Item in Module.GetPpiList():
    393         CheckDict = {'CName':Item.GetCName(),
    394                      'Usage':Item.GetUsage()}
    395         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    396 
    397     #

    398     # Check PcdCoded -> Entry

    399     #

    400     XmlTreeLevel = TopXmlTreeLevel + ['PcdCoded']
    401     for Item in Module.GetPcdList():
    402         if Item == None:
    403             CheckDict = {'PcdEntry':''}
    404             IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    405 
    406     XmlTreeLevel = TopXmlTreeLevel + ['PcdCoded', 'PcdEntry']
    407     for Item in Module.GetPcdList():
    408         CheckDict = {'TokenSpaceGuidCname':Item.GetTokenSpaceGuidCName(),
    409                      'CName':Item.GetCName(),
    410                      'PcdUsage':Item.GetValidUsage(),
    411                      'PcdItemType':Item.GetItemType()}
    412         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    413 
    414     #

    415     # Check Externs -> Extern

    416     #

    417     XmlTreeLevel = TopXmlTreeLevel + ['Externs']
    418     for Item in Module.GetExternList():
    419         if Item == None:
    420             CheckDict = {'Extern':''}
    421             IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    422 
    423     #

    424     # If SupArchList is used to identify different EntryPoint, UnloadImage, Constructor/Destructor elements and 

    425     # that SupArchList does not match ModuleSurfaceArea.ModuleProperties:SupArchList, the tool must exit gracefully,

    426     # informing the user that the EDK II Build system does not support different EntryPoint, UnloadImage, 

    427     # Constructor or Destructor elements based on Architecture type.  Two SupArchList attributes are considered 

    428     # identical if it lists the same CPU architectures in any order.

    429     #

    430     for Item in Module.GetExternList():
    431         if len(Item.SupArchList) > 0:
    432             if not IsEqualList(Item.SupArchList, Module.SupArchList):
    433                 Logger.Error('\nUPT',
    434                              PARSER_ERROR,
    435                              ERR_XML_INVALID_EXTERN_SUPARCHLIST % (str(Item.SupArchList), str(Module.SupArchList)),
    436                              RaiseError=True)
    437 
    438     #

    439     # Check DistributionPackage -> ModuleSurfaceArea -> UserExtensions

    440     #

    441     XmlTreeLevel = TopXmlTreeLevel + ['UserExtensions']
    442     for Item in Module.GetUserExtensionList():
    443         CheckDict = {'UserId':Item.GetUserID(), 'Identifier':Item.GetIdentifier()}
    444         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    445 
    446     #

    447     # Check DistributionPackage -> PackageSurfaceArea -> MiscellaneousFiles -> Filename

    448     #

    449     XmlTreeLevel = TopXmlTreeLevel + ['MiscellaneousFiles']
    450     for Item in Module.GetMiscFileList():
    451         if not Item.GetFileList():
    452             CheckDict = {'Filename':'', }
    453             IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    454         for File in Item.GetFileList():
    455             CheckDict = {'Filename':File.GetURI(), }
    456 
    457 ## ValidateMS2

    458 #

    459 # Check if any required item is missing in ModuleSurfaceArea

    460 #

    461 # @param Module: The ModuleSurfaceArea to be checked

    462 # @param XmlTreeLevel: The top level of Module 

    463 #

    464 def ValidateMS2(Module, TopXmlTreeLevel):
    465     #

    466     # Check Header

    467     #

    468     XmlTreeLevel = TopXmlTreeLevel + ['Header']
    469     CheckDict = Sdict()
    470     CheckDict['Name'] = Module.GetName()
    471     CheckDict['BaseName'] = Module.GetBaseName()
    472     CheckDict['GUID'] = Module.GetGuid()
    473     CheckDict['Version'] = Module.GetVersion()
    474     IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    475 
    476     #

    477     # Check ModuleProperties

    478     #

    479     XmlTreeLevel = TopXmlTreeLevel + ['ModuleProperties']
    480     CheckDict = {'ModuleType':Module.GetModuleType(),
    481                  'Path':Module.GetModulePath()}
    482     IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    483 
    484     if not IsValidInstallPath(Module.GetModulePath()):
    485         Logger.Error("UPT", FORMAT_INVALID, ERR_FILE_NAME_INVALIDE % Module.GetModulePath())
    486 
    487     #

    488     # Check ModuleProperties->BootMode 

    489     #

    490     XmlTreeLevel = TopXmlTreeLevel + ['ModuleProperties'] + ['BootMode']
    491     for Item in Module.GetBootModeList():
    492         CheckDict = {'Usage':Item.GetUsage(),
    493                      'SupportedBootModes':Item.GetSupportedBootModes()}
    494         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    495 
    496     #

    497     # Check ModuleProperties->Event 

    498     #

    499     XmlTreeLevel = TopXmlTreeLevel + ['ModuleProperties'] + ['Event']
    500     for Item in Module.GetEventList():
    501         CheckDict = {'Usage':Item.GetUsage(),
    502                      'EventType':Item.GetEventType()}
    503         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    504 
    505     #

    506     # Check ModuleProperties->Hob 

    507     #

    508     XmlTreeLevel = TopXmlTreeLevel + ['ModuleProperties'] + ['HOB']
    509     for Item in Module.GetHobList():
    510         CheckDict = {'Usage':Item.GetUsage(),
    511                      'HobType':Item.GetHobType()}
    512         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    513 
    514     #

    515     # The UDP Specification supports the module type of UEFI_RUNTIME_DRIVER, which is not present in the EDK II INF 

    516     # File Specification v. 1.23, so UPT must perform the following translation that include the generation of a 

    517     # [Depex] section.

    518     #

    519     if Module.ModuleType == "UEFI_RUNTIME_DRIVER":
    520         Module.ModuleType = "DXE_RUNTIME_DRIVER"
    521         DxeObj = DepexObject()
    522         DxeObj.SetDepex("gEfiBdsArchProtocolGuid AND \ngEfiCpuArchProtocolGuid AND\n" + \
    523                         "gEfiMetronomeArchProtocolGuid AND \ngEfiMonotonicCounterArchProtocolGuid AND\n" + \
    524                         "gEfiRealTimeClockArchProtocolGuid AND \ngEfiResetArchProtocolGuid AND\n" + \
    525                         "gEfiRuntimeArchProtocolGuid AND \ngEfiSecurityArchProtocolGuid AND\n" + \
    526                         "gEfiTimerArchProtocolGuid AND \ngEfiVariableWriteArchProtocolGuid AND\n" + \
    527                         "gEfiVariableArchProtocolGuid AND \ngEfiWatchdogTimerArchProtocolGuid")
    528         DxeObj.SetModuleType(['DXE_RUNTIME_DRIVER'])
    529         Module.PeiDepex = []
    530         Module.DxeDepex = []
    531         Module.SmmDepex = []
    532         Module.DxeDepex.append(DxeObj)
    533 
    534     #

    535     # Check LibraryClassDefinitions -> LibraryClass

    536     #

    537     XmlTreeLevel = TopXmlTreeLevel + ['LibraryClassDefinitions']
    538     for Item in Module.GetLibraryClassList():
    539         if Item == None:
    540             CheckDict = {'LibraryClass':''}
    541             IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    542 
    543     XmlTreeLevel = TopXmlTreeLevel + ['LibraryClassDefinitions', 'LibraryClass']
    544 
    545     IsLibraryModule = False
    546     LibrarySupModList = []
    547     for Item in Module.GetLibraryClassList():
    548         CheckDict = {'Keyword':Item.GetLibraryClass(),
    549                      'Usage':Item.GetUsage()}
    550         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    551         #

    552         # If the LibraryClass:SupModList is not "UNDEFINED" the LIBRARY_CLASS entry must have the list 

    553         # appended using the format:

    554         # LIBRARY_CLASS = <ClassName> ["|" <Edk2ModuleTypeList>]

    555         #

    556         # Edk2ModuleTypeList ::= <ModuleType> [" " <ModuleType>]{0,}

    557         # <ModuleTypes>      ::= {"BASE"} {"SEC"} {"PEI_CORE"} {"PEIM"}

    558         #                       {"DXE_CORE"} {"DXE_DRIVER"} {"SMM_CORE"}

    559         #                       {"DXE_SMM_DRIVER"} {"DXE_RUNTIME_DRIVER"}

    560         #                       {"DXE_SAL_DRIVER"} {"UEFI_DRIVER"}

    561         #                       {"UEFI_APPLICATION"} {"USER_DEFINED"}

    562         #

    563         if len(Item.SupModuleList) > 0:
    564             for SupModule in Item.SupModuleList:
    565                 if not IsValidInfMoudleType(SupModule):
    566                     Logger.Error('\nUPT',
    567                                  PARSER_ERROR,
    568                                  ERR_XML_INVALID_LIB_SUPMODLIST % (Item.LibraryClass, str(SupModule)),
    569                                  RaiseError=True)
    570 
    571         if Item.Usage == 'PRODUCES' or Item.Usage == 'SOMETIMES_PRODUCES':
    572             IsLibraryModule = True
    573             LibrarySupModList = Item.SupModuleList
    574 
    575 
    576     #

    577     # For Library modules (indicated by a LIBRARY_CLASS statement in the [Defines] section)                  

    578     # If the SupModList attribute of the CONSTRUCTOR or DESTRUCTOR element does not match the Supported Module 

    579     # Types listed after "LIBRARY_CLASS = <Keyword> |", the tool should gracefully exit with an error message 

    580     # stating that there is a conflict in the module types the CONSTRUCTOR/DESTRUCTOR is to be used with and 

    581     # the Module types this Library supports.

    582     #

    583     if IsLibraryModule:
    584         for Item in Module.GetExternList():
    585             if Item.Constructor or Item.Destructor:
    586                 if hasattr(Item, 'SupModList') and len(Item.SupModList) > 0 and \
    587                    not IsEqualList(Item.SupModList, LibrarySupModList):
    588                     Logger.Error('\nUPT',
    589                          PARSER_ERROR,
    590                          ERR_XML_INVALID_EXTERN_SUPMODLIST % (str(Item.SupModList), str(LibrarySupModList)),
    591                          RaiseError=True)
    592 
    593     #

    594     # If the module is not a library module, the MODULE_TYPE listed in the ModuleSurfaceArea.Header must match the 

    595     # SupModList attribute.  If these conditions cannot be met, the tool must exit gracefully, informing the user 

    596     # that the EDK II Build system does not currently support the features required by this Module.

    597     #                   

    598     if not IsLibraryModule:
    599         for Item in Module.GetExternList():
    600             if hasattr(Item, 'SupModList') and len(Item.SupModList) > 0 and \
    601                not IsEqualList(Item.SupModList, [Module.ModuleType]):
    602                 Logger.Error('\nUPT',
    603                      PARSER_ERROR,
    604                      ERR_XML_INVALID_EXTERN_SUPMODLIST_NOT_LIB % (str(Module.ModuleType), str(Item.SupModList)),
    605                      RaiseError=True)
    606     #

    607     # Check SourceFiles

    608     #

    609     XmlTreeLevel = TopXmlTreeLevel + ['SourceFiles']
    610     for Item in Module.GetSourceFileList():
    611         if Item == None:
    612             CheckDict = {'Filename':''}
    613             IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    614 
    615     XmlTreeLevel = TopXmlTreeLevel + ['SourceFiles']
    616     for Item in Module.GetSourceFileList():
    617         CheckDict = {'Filename':Item.GetSourceFile()}
    618         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    619 
    620     for ItemCount in range(len(Module.GetBinaryFileList())):
    621         Item = Module.GetBinaryFileList()[ItemCount]
    622         if Item and len(Item.FileNamList) > 0 and Item.FileNamList[0].FileType == 'FREEFORM':
    623             Item.FileNamList[0].FileType = 'SUBTYPE_GUID'
    624             Module.GetBinaryFileList()[ItemCount] = Item
    625 
    626 ## ValidateMS3

    627 #

    628 # Check if any required item is missing in ModuleSurfaceArea

    629 #

    630 # @param Module: The ModuleSurfaceArea to be checked

    631 # @param XmlTreeLevel: The top level of Module 

    632 #

    633 def ValidateMS3(Module, TopXmlTreeLevel):
    634     #

    635     # Check PackageDependencies -> Package

    636     #

    637     XmlTreeLevel = TopXmlTreeLevel + ['PackageDependencies']
    638     for Item in Module.GetPackageDependencyList():
    639         if Item == None:
    640             CheckDict = {'Package':''}
    641             IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    642 
    643     XmlTreeLevel = TopXmlTreeLevel + ['PackageDependencies', 'Package']
    644     for Item in Module.GetPackageDependencyList():
    645         CheckDict = {'GUID':Item.GetGuid()}
    646         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    647 
    648     #

    649     # Check BinaryFiles -> BinaryFile

    650     #

    651     for Item in Module.GetBinaryFileList():
    652         if Item == None:
    653             XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles']
    654             CheckDict = {'BinaryFile':''}
    655             IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    656         if not Item.GetFileNameList():
    657             XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile']
    658             CheckDict = {'Filename':''}
    659             IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    660 
    661         XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile']
    662         for File in Item.GetFileNameList():
    663             CheckDict = {'Filename':File.GetFilename(),
    664                          'FileType':File.GetFileType()}
    665             IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    666         for AsBuilt in Item.GetAsBuiltList():
    667             #

    668             # Check LibInstance

    669             #                        

    670             if len(AsBuilt.LibraryInstancesList) == 1 and not AsBuilt.LibraryInstancesList[0]:
    671                 CheckDict = {'GUID':''}
    672                 XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt', 'LibraryInstances']
    673                 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    674                             
    675             for LibItem in AsBuilt.LibraryInstancesList:
    676                 CheckDict = {'Guid':LibItem.Guid,
    677                              'Version':LibItem.Version}
    678                 XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt', 'LibraryInstances']
    679                 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    680 
    681             #

    682             # Check PatchPcd

    683             #

    684             for PatchPcdItem in AsBuilt.PatchPcdList:
    685                 CheckDict = {'TokenSpaceGuidValue':PatchPcdItem.TokenSpaceGuidValue,
    686                              'PcdCName':PatchPcdItem.PcdCName,
    687                              'Token':PatchPcdItem.Token,
    688                              'DatumType':PatchPcdItem.DatumType,
    689                              'Value':PatchPcdItem.DefaultValue,
    690                              'Offset':PatchPcdItem.Offset}
    691                 XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt', 'PatchPcdValue']
    692                 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    693                 #

    694                 # Check PcdError

    695                 #

    696                 for PcdErrorItem in PatchPcdItem.PcdErrorsList:
    697                     CheckDict = {'ErrorNumber':PcdErrorItem.ErrorNumber}
    698                     XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt',
    699                                                       'PatchPcdValue', 'PcdError']
    700                     IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    701             #

    702             # Check PcdEx

    703             #

    704             for PcdExItem in AsBuilt.PcdExValueList:
    705                 CheckDict = {'TokenSpaceGuidValue':PcdExItem.TokenSpaceGuidValue,
    706                              'Token':PcdExItem.Token,
    707                              'DatumType':PcdExItem.DatumType}
    708                 XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt', 'PcdExValue']
    709                 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    710                 #

    711                 # Check PcdError

    712                 #

    713                 for PcdErrorItem in PcdExItem.PcdErrorsList:
    714                     CheckDict = {'ErrorNumber':PcdErrorItem.ErrorNumber}
    715                     XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt',
    716                                                       'PcdExValue', 'PcdError']
    717                     IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    718     #

    719     # Check SmmDepex

    720     #

    721     XmlTreeLevel = TopXmlTreeLevel + ['SmmDepex']
    722     for Item in Module.GetSmmDepex():
    723         CheckDict = {'Expression':Item.GetDepex()}
    724         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    725 
    726     #

    727     # Check PeiDepex

    728     #

    729     XmlTreeLevel = TopXmlTreeLevel + ['PeiDepex']
    730     for Item in Module.GetPeiDepex():
    731         CheckDict = {'Expression':Item.GetDepex()}
    732         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    733 
    734     #

    735     # Check DxeDepex

    736     #

    737     XmlTreeLevel = TopXmlTreeLevel + ['DxeDepex']
    738     for Item in Module.GetDxeDepex():
    739         CheckDict = {'Expression':Item.GetDepex()}
    740         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    741 
    742     #

    743     # Check <UserExtensions>

    744     #

    745     XmlTreeLevel = TopXmlTreeLevel + ['UserExtensions']
    746     for Item in Module.GetUserExtensionList():
    747         CheckDict = {'UserId':Item.GetUserID(), 'Identifier':Item.GetIdentifier()}
    748         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    749 
    750 ## ValidatePS1

    751 #

    752 # ValidatePS1

    753 #

    754 def ValidatePS1(Package):
    755     #

    756     # Check DistributionPackage -> PackageSurfaceArea -> Header

    757     #

    758     XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'Header']
    759     CheckDict = Sdict()
    760     CheckDict['Name'] = Package.GetName()
    761     CheckDict['BaseName'] = Package.GetBaseName()
    762     CheckDict['GUID'] = Package.GetGuid()
    763     CheckDict['Version'] = Package.GetVersion()
    764     CheckDict['PackagePath'] = Package.GetPackagePath()
    765 
    766     IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    767     if not IsValidInstallPath(Package.GetPackagePath()):
    768         Logger.Error("UPT", FORMAT_INVALID, ERR_FILE_NAME_INVALIDE % Package.GetPackagePath())
    769 
    770     #

    771     # Check DistributionPackage -> PackageSurfaceArea -> ClonedFrom

    772     #

    773     XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'ClonedFrom']
    774     for Item in Package.GetClonedFromList():
    775         if Item == None:
    776             CheckDict = Sdict()
    777             CheckDict['GUID'] = ''
    778             IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    779         CheckDict = Sdict()
    780         CheckDict['GUID'] = Item.GetPackageGuid()
    781         CheckDict['Version'] = Item.GetPackageVersion()
    782 
    783         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    784 
    785     #

    786     # Check DistributionPackage -> PackageSurfaceArea -> LibraryClassDeclarations -> LibraryClass

    787     #

    788     XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'LibraryClassDeclarations']
    789     for Item in Package.GetLibraryClassList():
    790         if Item == None:
    791             CheckDict = {'LibraryClass':''}
    792             IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    793 
    794     XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'LibraryClassDeclarations', 'LibraryClass']
    795     for Item in Package.GetLibraryClassList():
    796         CheckDict = {'Keyword':Item.GetLibraryClass(),
    797                      'HeaderFile':Item.GetIncludeHeader()}
    798         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    799 
    800     #

    801     # Check DistributionPackage -> PackageSurfaceArea -> IndustryStandardIncludes -> IndustryStandardHeader

    802     #

    803     XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'IndustryStandardIncludes']
    804     for Item in Package.GetStandardIncludeFileList():
    805         if Item == None:
    806             CheckDict = {'IndustryStandardHeader':''}
    807             IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    808 
    809     XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'IndustryStandardIncludes', 'IndustryStandardHeader']
    810     for Item in Package.GetStandardIncludeFileList():
    811         CheckDict = {'HeaderFile':Item.GetFilePath()}
    812         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    813 
    814     #

    815     # Check DistributionPackage -> PackageSurfaceArea -> PackageIncludes -> PackageHeader

    816     #

    817     XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PackageIncludes']
    818     for Item in Package.GetPackageIncludeFileList():
    819         if Item == None:
    820             CheckDict = {'PackageHeader':''}
    821             IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    822 
    823     XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PackageIncludes', 'PackageHeader']
    824     for Item in Package.GetPackageIncludeFileList():
    825         CheckDict = {'HeaderFile':Item.GetFilePath()}
    826         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    827 
    828 ## ValidatePS2

    829 #

    830 # ValidatePS2

    831 #

    832 def ValidatePS2(Package):
    833     #

    834     # Check DistributionPackage -> PackageSurfaceArea -> Modules -> ModuleSurfaceArea

    835     #

    836     XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'Modules', 'ModuleSurfaceArea']
    837     for Item in Package.GetModuleDict().values():
    838         ValidateMS(Item, XmlTreeLevel)
    839 
    840     #

    841     # Check DistributionPackage -> PackageSurfaceArea -> GuidDeclarations Entry

    842     #

    843     XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'GuidDeclarations']
    844     for Item in Package.GetGuidList():
    845         if Item == None:
    846             CheckDict = {'Entry':''}
    847             IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    848 
    849     XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'GuidDeclarations', 'Entry']
    850     for Item in Package.GetGuidList():
    851         CheckDict = {'CName':Item.GetCName(),
    852                      'GuidValue':Item.GetGuid()}
    853         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    854 
    855     #

    856     # Check DistributionPackage -> PackageSurfaceArea -> ProtocolDeclarations -> Entry

    857     #

    858     XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'ProtocolDeclarations']
    859     for Item in Package.GetProtocolList():
    860         if Item == None:
    861             CheckDict = {'Entry':''}
    862             IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    863 
    864     XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'ProtocolDeclarations', 'Entry']
    865     for Item in Package.GetProtocolList():
    866         CheckDict = {'CName':Item.GetCName(),
    867                      'GuidValue':Item.GetGuid()}
    868         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    869 
    870     #

    871     # Check DistributionPackage -> PackageSurfaceArea -> PpiDeclarations -> Entry

    872     #

    873     XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PpiDeclarations']
    874     for Item in Package.GetPpiList():
    875         if Item == None:
    876             CheckDict = {'Entry':''}
    877             IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    878 
    879     XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PpiDeclarations', 'Entry']
    880     for Item in Package.GetPpiList():
    881         CheckDict = {'CName':Item.GetCName(),
    882                      'GuidValue':Item.GetGuid()}
    883         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    884 
    885     #

    886     # Check DistributionPackage -> PackageSurfaceArea -> PcdDeclarations -> Entry

    887     #

    888     XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PcdDeclarations']
    889     for Item in Package.GetPcdList():
    890         if Item == None:
    891             CheckDict = {'PcdEntry':''}
    892             IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    893 
    894     XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PcdDeclarations', 'PcdEntry']
    895     for Item in Package.GetPcdList():
    896         CheckDict = {'TokenSpaceGuidCname':Item.GetTokenSpaceGuidCName(),
    897                      'Token':Item.GetToken(),
    898                      'CName':Item.GetCName(),
    899                      'DatumType':Item.GetDatumType(),
    900                      'ValidUsage':Item.GetValidUsage(),
    901                      'DefaultValue':Item.GetDefaultValue()}
    902         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    903 
    904     #

    905     # Check DistributionPackage -> PackageSurfaceArea -> UserExtensions

    906     #

    907     XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'UserExtensions']
    908     for Item in Package.GetUserExtensionList():
    909         CheckDict = {'UserId':Item.GetUserID(), 'Identifier':Item.GetIdentifier()}
    910         IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    911 
    912     #

    913     # Check DistributionPackage -> PackageSurfaceArea -> MiscellaneousFiles -> Filename

    914     #

    915     XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'MiscellaneousFiles']
    916     for Item in Package.GetMiscFileList():
    917         if not Item.GetFileList():
    918             CheckDict = {'Filename':'', }
    919             IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    920         for File in Item.GetFileList():
    921             CheckDict = {'Filename':File.GetURI(), }
    922             IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    923 
    924 ## ValidatePackageSurfaceArea

    925 #

    926 # Check if any required item is missing in  PackageSurfaceArea

    927 #

    928 # @param Package: The PackageSurfaceArea to be checked 

    929 #

    930 def ValidatePackageSurfaceArea(Package):
    931     ValidatePS1(Package)
    932     ValidatePS2(Package)
    933