+ ## Get HII EX PCDs which maybe used by VFR\r
+ #\r
+ # efivarstore used by VFR may relate with HII EX PCDs\r
+ # Get the variable name and GUID from efivarstore and HII EX PCD\r
+ # List the HII EX PCDs in As Built INF if both name and GUID match.\r
+ #\r
+ # @retval list HII EX PCDs\r
+ #\r
+ def _GetPcdsMaybeUsedByVfr(self):\r
+ if not self.SourceFileList:\r
+ return []\r
+\r
+ NameGuids = []\r
+ for SrcFile in self.SourceFileList:\r
+ if SrcFile.Ext.lower() != '.vfr':\r
+ continue\r
+ Vfri = os.path.join(self.OutputDir, SrcFile.BaseName + '.i')\r
+ if not os.path.exists(Vfri):\r
+ continue\r
+ VfriFile = open(Vfri, 'r')\r
+ Content = VfriFile.read()\r
+ VfriFile.close()\r
+ Pos = Content.find('efivarstore')\r
+ while Pos != -1:\r
+ #\r
+ # Make sure 'efivarstore' is the start of efivarstore statement\r
+ # In case of the value of 'name' (name = efivarstore) is equal to 'efivarstore'\r
+ #\r
+ Index = Pos - 1\r
+ while Index >= 0 and Content[Index] in ' \t\r\n':\r
+ Index -= 1\r
+ if Index >= 0 and Content[Index] != ';':\r
+ Pos = Content.find('efivarstore', Pos + len('efivarstore'))\r
+ continue\r
+ #\r
+ # 'efivarstore' must be followed by name and guid\r
+ #\r
+ Name = gEfiVarStoreNamePattern.search(Content, Pos)\r
+ if not Name:\r
+ break\r
+ Guid = gEfiVarStoreGuidPattern.search(Content, Pos)\r
+ if not Guid:\r
+ break\r
+ NameArray = ConvertStringToByteArray('L"' + Name.group(1) + '"')\r
+ NameGuids.append((NameArray, GuidStructureStringToGuidString(Guid.group(1))))\r
+ Pos = Content.find('efivarstore', Name.end())\r
+ if not NameGuids:\r
+ return []\r
+ HiiExPcds = []\r
+ for Pcd in self.PlatformInfo.Platform.Pcds.values():\r
+ if Pcd.Type != TAB_PCDS_DYNAMIC_EX_HII:\r
+ continue\r
+ for SkuName in Pcd.SkuInfoList:\r
+ SkuInfo = Pcd.SkuInfoList[SkuName]\r
+ Name = ConvertStringToByteArray(SkuInfo.VariableName)\r
+ Value = GuidValue(SkuInfo.VariableGuid, self.PlatformInfo.PackageList)\r
+ if not Value:\r
+ continue\r
+ Guid = GuidStructureStringToGuidString(Value)\r
+ if (Name, Guid) in NameGuids and Pcd not in HiiExPcds:\r
+ HiiExPcds.append(Pcd)\r
+ break\r
+\r
+ return HiiExPcds\r
+\r
+ def _GenOffsetBin(self):\r
+ VfrUniBaseName = {}\r
+ for SourceFile in self.Module.Sources:\r
+ if SourceFile.Type.upper() == ".VFR" :\r
+ #\r
+ # search the .map file to find the offset of vfr binary in the PE32+/TE file. \r
+ #\r
+ VfrUniBaseName[SourceFile.BaseName] = (SourceFile.BaseName + "Bin")\r
+ if SourceFile.Type.upper() == ".UNI" :\r
+ #\r
+ # search the .map file to find the offset of Uni strings binary in the PE32+/TE file. \r
+ #\r
+ VfrUniBaseName["UniOffsetName"] = (self.Name + "Strings")\r
+\r
+ if len(VfrUniBaseName) == 0:\r
+ return None\r
+ MapFileName = os.path.join(self.OutputDir, self.Name + ".map")\r
+ EfiFileName = os.path.join(self.OutputDir, self.Name + ".efi")\r
+ VfrUniOffsetList = GetVariableOffset(MapFileName, EfiFileName, VfrUniBaseName.values())\r
+ if not VfrUniOffsetList:\r
+ return None\r
+\r
+ OutputName = '%sOffset.bin' % self.Name\r
+ UniVfrOffsetFileName = os.path.join( self.OutputDir, OutputName)\r
+\r
+ try:\r
+ fInputfile = open(UniVfrOffsetFileName, "wb+", 0)\r
+ except:\r
+ EdkLogger.error("build", FILE_OPEN_FAILURE, "File open failed for %s" % UniVfrOffsetFileName,None)\r
+\r
+ # Use a instance of StringIO to cache data\r
+ fStringIO = StringIO('') \r
+\r
+ for Item in VfrUniOffsetList:\r
+ if (Item[0].find("Strings") != -1):\r
+ #\r
+ # UNI offset in image.\r
+ # GUID + Offset\r
+ # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }\r
+ #\r
+ UniGuid = [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]\r
+ UniGuid = [chr(ItemGuid) for ItemGuid in UniGuid]\r
+ fStringIO.write(''.join(UniGuid)) \r
+ UniValue = pack ('Q', int (Item[1], 16))\r
+ fStringIO.write (UniValue)\r
+ else:\r
+ #\r
+ # VFR binary offset in image.\r
+ # GUID + Offset\r
+ # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };\r
+ #\r
+ VfrGuid = [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]\r
+ VfrGuid = [chr(ItemGuid) for ItemGuid in VfrGuid]\r
+ fStringIO.write(''.join(VfrGuid)) \r
+ type (Item[1]) \r
+ VfrValue = pack ('Q', int (Item[1], 16))\r
+ fStringIO.write (VfrValue)\r
+ #\r
+ # write data into file.\r
+ #\r
+ try : \r
+ fInputfile.write (fStringIO.getvalue())\r
+ except:\r
+ EdkLogger.error("build", FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the "\r
+ "file been locked or using by other applications." %UniVfrOffsetFileName,None)\r
+\r
+ fStringIO.close ()\r
+ fInputfile.close ()\r
+ return OutputName\r
+\r