+\r
+/**\r
+ VariableLock DynamicHiiPcd.\r
+\r
+ @param[in] IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,\r
+ If FALSE, the pcd entry is initialized in DXE phase.\r
+ @param[in] VariableLock Pointer to VariableLockProtocol.\r
+\r
+**/\r
+VOID\r
+VariableLockDynamicHiiPcd (\r
+ IN BOOLEAN IsPeiDb,\r
+ IN EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ PCD_DATABASE_INIT *Database;\r
+ UINT32 LocalTokenCount; \r
+ UINTN TokenNumber;\r
+ UINT32 LocalTokenNumber;\r
+ UINTN Offset;\r
+ EFI_GUID *GuidTable;\r
+ UINT8 *StringTable;\r
+ VARIABLE_HEAD *VariableHead;\r
+ EFI_GUID *Guid;\r
+ UINT16 *Name;\r
+\r
+ Database = IsPeiDb ? mPcdDatabase.PeiDb: mPcdDatabase.DxeDb;\r
+ LocalTokenCount = IsPeiDb ? mPeiLocalTokenCount: mDxeLocalTokenCount;\r
+\r
+ //\r
+ // Go through PCD database to find out DynamicHii PCDs.\r
+ //\r
+ for (TokenNumber = 1; TokenNumber <= LocalTokenCount; TokenNumber++) {\r
+ if (IsPeiDb) {\r
+ LocalTokenNumber = GetLocalTokenNumber (TRUE, TokenNumber);\r
+ } else {\r
+ LocalTokenNumber = GetLocalTokenNumber (FALSE, TokenNumber + mPeiLocalTokenCount);\r
+ }\r
+ if ((LocalTokenNumber & PCD_TYPE_HII) != 0) {\r
+ Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
+ VariableHead = (VARIABLE_HEAD *) ((UINT8 *) Database + Offset);\r
+ //\r
+ // Why not to set property by VarCheckProtocol with Attributes and Property directly here?\r
+ // It is because that set property by VarCheckProtocol will indicate the variable to\r
+ // be a system variable, but the unknown max size of the variable is dangerous to\r
+ // the system variable region.\r
+ //\r
+ if ((VariableHead->Property & VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY) != 0) {\r
+ //\r
+ // DynamicHii PCD with RO property set in *.dsc.\r
+ //\r
+ StringTable = (UINT8 *) ((UINT8 *) Database + Database->StringTableOffset);\r
+ GuidTable = (EFI_GUID *) ((UINT8 *) Database + Database->GuidTableOffset);\r
+ Guid = GuidTable + VariableHead->GuidTableIndex;\r
+ Name = (UINT16*) (StringTable + VariableHead->StringIndex);\r
+ Status = VariableLock->RequestToLock (VariableLock, Name, Guid);\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ VariableLockProtocol callback\r
+ to lock the variables referenced by DynamicHii PCDs with RO property set in *.dsc.\r
+\r
+ @param[in] Event Event whose notification function is being invoked.\r
+ @param[in] Context Pointer to the notification function's context.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+VariableLockCallBack (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock;\r
+\r
+ Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **) &VariableLock);\r
+ if (!EFI_ERROR (Status)) {\r
+ VariableLockDynamicHiiPcd (TRUE, VariableLock);\r
+ VariableLockDynamicHiiPcd (FALSE, VariableLock);\r
+ }\r
+}\r
+\r