+ Status = FindVariable (VariableName, VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal);\r
+ if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ if (VariableName[0] != 0) {\r
+ //\r
+ // If variable name is not NULL, get next variable.\r
+ //\r
+ Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);\r
+ }\r
+\r
+ while (TRUE) {\r
+ //\r
+ // If both volatile and non-volatile variable store are parsed,\r
+ // return not found.\r
+ //\r
+ if (Variable.CurrPtr >= Variable.EndPtr || Variable.CurrPtr == NULL) {\r
+ Variable.Volatile = (BOOLEAN) (Variable.Volatile ^ ((BOOLEAN) 0x1));\r
+ if (!Variable.Volatile) {\r
+ Variable.StartPtr = GetStartPointer ((VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);\r
+ Variable.EndPtr = GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase));\r
+ } else {\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
+ }\r
+\r
+ Variable.CurrPtr = Variable.StartPtr;\r
+ if (!IsValidVariableHeader (Variable.CurrPtr)) {\r
+ continue;\r
+ }\r
+ }\r
+ //\r
+ // Variable is found\r
+ //\r
+ if (IsValidVariableHeader (Variable.CurrPtr) && Variable.CurrPtr->State == VAR_ADDED) {\r
+ if ((AtRuntime () && ((Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) == 0) {\r
+ VarNameSize = NameSizeOfVariable (Variable.CurrPtr);\r
+ ASSERT (VarNameSize != 0);\r
+\r
+ if (VarNameSize <= *VariableNameSize) {\r
+ CopyMem (\r
+ VariableName,\r
+ GetVariableNamePtr (Variable.CurrPtr),\r
+ VarNameSize\r
+ );\r
+ CopyMem (\r
+ VendorGuid,\r
+ &Variable.CurrPtr->VendorGuid,\r
+ sizeof (EFI_GUID)\r
+ );\r
+ Status = EFI_SUCCESS;\r
+ } else {\r
+ Status = EFI_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ *VariableNameSize = VarNameSize;\r
+ goto Done;\r
+ }\r
+ }\r
+\r
+ Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);\r
+ }\r
+\r
+Done:\r
+ ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
+ return Status;\r
+}\r
+\r
+/**\r
+\r
+ This code sets variable in storage blocks (Volatile or Non-Volatile).\r
+\r
+ @param VariableName Name of Variable to be found.\r
+ @param VendorGuid Variable vendor GUID.\r
+ @param Attributes Attribute value of the variable found\r
+ @param DataSize Size of Data found. If size is less than the\r
+ data, this value contains the required size.\r
+ @param Data Data pointer.\r
+\r
+ @return EFI_INVALID_PARAMETER Invalid parameter.\r
+ @return EFI_SUCCESS Set successfully.\r
+ @return EFI_OUT_OF_RESOURCES Resource not enough to set variable.\r
+ @return EFI_NOT_FOUND Not found.\r
+ @return EFI_WRITE_PROTECTED Variable is read-only.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VariableServiceSetVariable (\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid,\r
+ IN UINT32 Attributes,\r
+ IN UINTN DataSize,\r
+ IN VOID *Data\r
+ )\r
+{\r
+ VARIABLE_POINTER_TRACK Variable;\r
+ EFI_STATUS Status;\r
+ VARIABLE_HEADER *NextVariable;\r
+ EFI_PHYSICAL_ADDRESS Point;\r
+\r
+ //\r
+ // Check input parameters.\r
+ //\r
+ if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ } \r
+\r
+ if (DataSize != 0 && Data == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Not support authenticated variable write yet.\r
+ //\r
+ if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Make sure if runtime bit is set, boot service bit is set also.\r
+ //\r
+ if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // The size of the VariableName, including the Unicode Null in bytes plus\r
+ // the DataSize is limited to maximum size of PcdGet32 (PcdMaxHardwareErrorVariableSize)\r
+ // bytes for HwErrRec, and PcdGet32 (PcdMaxVariableSize) bytes for the others.\r
+ //\r
+ if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {\r
+ if ((DataSize > PcdGet32 (PcdMaxHardwareErrorVariableSize)) ||\r
+ (sizeof (VARIABLE_HEADER) + StrSize (VariableName) + DataSize > PcdGet32 (PcdMaxHardwareErrorVariableSize))) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ //\r
+ // According to UEFI spec, HARDWARE_ERROR_RECORD variable name convention should be L"HwErrRecXXXX".\r
+ //\r
+ if (StrnCmp(VariableName, L"HwErrRec", StrLen(L"HwErrRec")) != 0) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ } else {\r
+ //\r
+ // The size of the VariableName, including the Unicode Null in bytes plus\r
+ // the DataSize is limited to maximum size of PcdGet32 (PcdMaxVariableSize) bytes.\r
+ //\r
+ if ((DataSize > PcdGet32 (PcdMaxVariableSize)) ||\r
+ (sizeof (VARIABLE_HEADER) + StrSize (VariableName) + DataSize > PcdGet32 (PcdMaxVariableSize))) {\r
+ return EFI_INVALID_PARAMETER;\r
+ } \r
+ } \r
+\r
+ AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
+\r
+ //\r
+ // Consider reentrant in MCA/INIT/NMI. It needs be reupdated.\r
+ //\r
+ if (1 < InterlockedIncrement (&mVariableModuleGlobal->VariableGlobal.ReentrantState)) {\r
+ Point = mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase;\r
+ //\r
+ // Parse non-volatile variable data and get last variable offset.\r
+ //\r
+ NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *) (UINTN) Point);\r
+ while ((NextVariable < GetEndPointer ((VARIABLE_STORE_HEADER *) (UINTN) Point)) \r
+ && IsValidVariableHeader (NextVariable)) {\r
+ NextVariable = GetNextVariablePtr (NextVariable);\r
+ }\r
+ mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN) NextVariable - (UINTN) Point;\r
+ }\r
+\r
+ //\r
+ // Check whether the input variable is already existed.\r
+ //\r
+ FindVariable (VariableName, VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal);\r
+\r
+ //\r
+ // Hook the operation of setting PlatformLangCodes/PlatformLang and LangCodes/Lang.\r
+ //\r
+ AutoUpdateLangVariable (VariableName, Data, DataSize);\r
+\r
+ Status = UpdateVariable (VariableName, VendorGuid, Data, DataSize, Attributes, &Variable);\r
+\r
+ InterlockedDecrement (&mVariableModuleGlobal->VariableGlobal.ReentrantState);\r
+ ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+\r
+ This code returns information about the EFI variables.\r
+\r
+ @param Attributes Attributes bitmask to specify the type of variables\r
+ on which to return information.\r
+ @param MaximumVariableStorageSize Pointer to the maximum size of the storage space available\r
+ for the EFI variables associated with the attributes specified.\r
+ @param RemainingVariableStorageSize Pointer to the remaining size of the storage space available\r
+ for EFI variables associated with the attributes specified.\r
+ @param MaximumVariableSize Pointer to the maximum size of an individual EFI variables\r
+ associated with the attributes specified.\r
+\r
+ @return EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied.\r
+ @return EFI_SUCCESS Query successfully.\r
+ @return EFI_UNSUPPORTED The attribute is not supported on this platform.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VariableServiceQueryVariableInfo (\r
+ IN UINT32 Attributes,\r
+ OUT UINT64 *MaximumVariableStorageSize,\r
+ OUT UINT64 *RemainingVariableStorageSize,\r
+ OUT UINT64 *MaximumVariableSize\r
+ )\r
+{\r
+ VARIABLE_HEADER *Variable;\r
+ VARIABLE_HEADER *NextVariable;\r
+ UINT64 VariableSize;\r
+ VARIABLE_STORE_HEADER *VariableStoreHeader;\r
+ UINT64 CommonVariableTotalSize;\r
+ UINT64 HwErrVariableTotalSize;\r
+\r
+ CommonVariableTotalSize = 0;\r
+ HwErrVariableTotalSize = 0;\r
+\r
+ if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL || Attributes == 0) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == 0) {\r
+ //\r
+ // Make sure the Attributes combination is supported by the platform.\r
+ //\r
+ return EFI_UNSUPPORTED; \r
+ } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {\r
+ //\r
+ // Make sure if runtime bit is set, boot service bit is set also.\r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+ } else if (AtRuntime () && ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) {\r
+ //\r
+ // Make sure RT Attribute is set if we are in Runtime phase.\r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+ } else if ((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {\r
+ //\r
+ // Make sure Hw Attribute is set with NV.\r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+ } else if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+ //\r
+ // Not support authentiated variable write yet.\r
+ //\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
+\r