Revision: 15388
          http://sourceforge.net/p/edk2/code/15388
Author:   lzeng14
Date:     2014-03-25 06:56:55 +0000 (Tue, 25 Mar 2014)
Log Message:
-----------
MdeModulePkg/SecurityPkg Variable: Calculate enough space for PlatformLang and 
Lang variables and use PcdUefiVariableDefaultLangDeprecate to turn off auto 
update between PlatformLang and Lang variables.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Star Zeng <[email protected]>
Reviewed-by: Jiewen Yao <[email protected]>
Reviewed-by: Guo Dong <[email protected]>

Modified Paths:
--------------
    trunk/edk2/IntelFrameworkModulePkg/Universal/BdsDxe/Language.c
    trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
    trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
    trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
    trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
    trunk/edk2/MdePkg/MdePkg.dec
    trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
    trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h
    
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf
    trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf

Modified: trunk/edk2/IntelFrameworkModulePkg/Universal/BdsDxe/Language.c
===================================================================
--- trunk/edk2/IntelFrameworkModulePkg/Universal/BdsDxe/Language.c      
2014-03-25 05:04:21 UTC (rev 15387)
+++ trunk/edk2/IntelFrameworkModulePkg/Universal/BdsDxe/Language.c      
2014-03-25 06:56:55 UTC (rev 15388)
@@ -462,7 +462,7 @@
   if (LangCodesSettingRequired) {
     if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
       //
-      // UEFI 2.1 depricated this variable so we support turning it off
+      // UEFI 2.0 depricated this variable so we support turning it off
       //
       Status = gRT->SetVariable (
                       L"LangCodes",
@@ -492,7 +492,7 @@
 
   if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
     //
-    // UEFI 2.1 depricated this variable so we support turning it off
+    // UEFI 2.0 depricated this variable so we support turning it off
     //
     InitializeLangVariable (L"Lang", LangCodes, (CHAR8 *) PcdGetPtr 
(PcdUefiVariableDefaultLang), TRUE);
   }

Modified: trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
===================================================================
--- trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c    
2014-03-25 05:04:21 UTC (rev 15387)
+++ trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c    
2014-03-25 06:56:55 UTC (rev 15388)
@@ -1259,6 +1259,121 @@
 }
 
 /**
+  This function is to check if the remaining variable space is enough to set
+  all Variables from argument list successfully. The purpose of the check
+  is to keep the consistency of the Variables to be in variable storage.
+
+  Note: Variables are assumed to be in same storage.
+  The set sequence of Variables will be same with the sequence of 
VariableEntry from argument list,
+  so follow the argument sequence to check the Variables.
+
+  @param[in] Attributes         Variable attributes for Variable entries.
+  @param     ...                Variable argument list with type 
VARIABLE_ENTRY_CONSISTENCY *.
+                                A NULL terminates the list.
+
+  @retval TRUE                  Have enough variable space to set the 
Variables successfully.
+  @retval FALSE                 No enough variable space to set the Variables 
successfully.
+
+**/
+BOOLEAN
+EFIAPI
+CheckRemainingSpaceForConsistency (
+  IN UINT32                     Attributes,
+  ...
+  )
+{
+  EFI_STATUS                    Status;
+  VA_LIST                       Args;
+  VARIABLE_ENTRY_CONSISTENCY    *VariableEntry;
+  UINT64                        MaximumVariableStorageSize;
+  UINT64                        RemainingVariableStorageSize;
+  UINT64                        MaximumVariableSize;
+  UINTN                         TotalNeededSize;
+  UINTN                         OriginalVarSize;
+  VARIABLE_STORE_HEADER         *VariableStoreHeader;
+  VARIABLE_POINTER_TRACK        VariablePtrTrack;
+  VARIABLE_HEADER               *NextVariable;
+
+  //
+  // Non-Volatile related.
+  //
+  VariableStoreHeader = mNvVariableCache;
+
+  Status = VariableServiceQueryVariableInfoInternal (
+             Attributes,
+             &MaximumVariableStorageSize,
+             &RemainingVariableStorageSize,
+             &MaximumVariableSize
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  TotalNeededSize = 0;
+  VA_START (Args, Attributes);
+  VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+  while (VariableEntry != NULL) {
+    TotalNeededSize += VariableEntry->VariableSize;
+    VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+  }
+  VA_END (Args);
+
+  if (RemainingVariableStorageSize >= TotalNeededSize) {
+    //
+    // Already have enough space.
+    //
+    return TRUE;
+  } else if (AtRuntime ()) {
+    //
+    // At runtime, no reclaim.
+    // The original variable space of Variables can't be reused.
+    //
+    return FALSE;
+  }
+
+  VA_START (Args, Attributes);
+  VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+  while (VariableEntry != NULL) {
+    //
+    // Check if Variable[Index] has been present and get its size.
+    //
+    OriginalVarSize = 0;
+    VariablePtrTrack.StartPtr = GetStartPointer (VariableStoreHeader);
+    VariablePtrTrack.EndPtr   = GetEndPointer   (VariableStoreHeader);
+    Status = FindVariableEx (
+               VariableEntry->Name,
+               VariableEntry->Guid,
+               FALSE,
+               &VariablePtrTrack
+               );
+    if (!EFI_ERROR (Status)) {
+      //
+      // Get size of Variable[Index].
+      //
+      NextVariable = GetNextVariablePtr (VariablePtrTrack.CurrPtr);
+      OriginalVarSize = (UINTN) NextVariable - (UINTN) 
VariablePtrTrack.CurrPtr;
+      //
+      // Add the original size of Variable[Index] to remaining variable 
storage size.
+      //
+      RemainingVariableStorageSize += OriginalVarSize;
+    }
+    if (VariableEntry->VariableSize > RemainingVariableStorageSize) {
+      //
+      // No enough space for Variable[Index].
+      //
+      VA_END (Args);
+      return FALSE;
+    }
+    //
+    // Sub the (new) size of Variable[Index] from remaining variable storage 
size.
+    //
+    RemainingVariableStorageSize -= VariableEntry->VariableSize;
+    VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+  }
+  VA_END (Args);
+
+  return TRUE;
+}
+
+/**
   Hook the operations in PlatformLangCodes, LangCodes, PlatformLang and Lang.
 
   When setting Lang/LangCodes, simultaneously update 
PlatformLang/PlatformLangCodes.
@@ -1292,6 +1407,9 @@
   UINT32                 Attributes;
   VARIABLE_POINTER_TRACK Variable;
   BOOLEAN                SetLanguageCodes;
+  UINTN                  VarNameSize;
+  UINTN                  VarDataSize;
+  VARIABLE_ENTRY_CONSISTENCY VariableEntry[2];
 
   //
   // Don't do updates for delete operation
@@ -1414,14 +1532,39 @@
         BestLang = GetLangFromSupportedLangCodes 
(mVariableModuleGlobal->LangCodes, Index, TRUE);
 
         //
-        // Successfully convert PlatformLang to Lang, and set the BestLang 
value into Lang variable simultaneously.
+        // Calculate the needed variable size for Lang variable.
         //
-        FindVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, 
&Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
+        VarNameSize = StrSize (EFI_LANG_VARIABLE_NAME);
+        VarDataSize = ISO_639_2_ENTRY_SIZE + 1;
+        VariableEntry[0].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize 
+ GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);
+        VariableEntry[0].VariableSize = HEADER_ALIGN 
(VariableEntry[0].VariableSize);
+        VariableEntry[0].Guid = &gEfiGlobalVariableGuid;
+        VariableEntry[0].Name = EFI_LANG_VARIABLE_NAME;
+        //
+        // Calculate the needed variable size for PlatformLang variable.
+        //
+        VarNameSize = StrSize (EFI_PLATFORM_LANG_VARIABLE_NAME);
+        VarDataSize = AsciiStrSize (BestPlatformLang);
+        VariableEntry[1].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize 
+ GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);
+        VariableEntry[1].VariableSize = HEADER_ALIGN 
(VariableEntry[1].VariableSize);
+        VariableEntry[1].Guid = &gEfiGlobalVariableGuid;
+        VariableEntry[1].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;
+        if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, 
&VariableEntry[0], &VariableEntry[1], NULL)) {
+          //
+          // No enough variable space to set both Lang and PlatformLang 
successfully.
+          //
+          Status = EFI_OUT_OF_RESOURCES;
+        } else {
+          //
+          // Successfully convert PlatformLang to Lang, and set the BestLang 
value into Lang variable simultaneously.
+          //
+          FindVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, 
&Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
 
-        Status = UpdateVariable (EFI_LANG_VARIABLE_NAME, 
&gEfiGlobalVariableGuid, BestLang,
-                                 ISO_639_2_ENTRY_SIZE + 1, Attributes, 
&Variable);
+          Status = UpdateVariable (EFI_LANG_VARIABLE_NAME, 
&gEfiGlobalVariableGuid, BestLang,
+                                   ISO_639_2_ENTRY_SIZE + 1, Attributes, 
&Variable);
+        }
 
-        DEBUG ((EFI_D_INFO, "Variable Driver Auto Update PlatformLang, 
PlatformLang:%a, Lang:%a: Status: %r\n", BestPlatformLang, BestLang, Status));
+        DEBUG ((EFI_D_INFO, "Variable Driver Auto Update PlatformLang, 
PlatformLang:%a, Lang:%a Status: %r\n", BestPlatformLang, BestLang, Status));
       }
     }
 
@@ -1446,19 +1589,51 @@
         BestPlatformLang = GetLangFromSupportedLangCodes 
(mVariableModuleGlobal->PlatformLangCodes, Index, FALSE);
 
         //
-        // Successfully convert Lang to PlatformLang, and set the 
BestPlatformLang value into PlatformLang variable simultaneously.
+        // Calculate the needed variable size for PlatformLang variable.
         //
-        FindVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, 
&gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, 
FALSE);
+        VarNameSize = StrSize (EFI_PLATFORM_LANG_VARIABLE_NAME);
+        VarDataSize = AsciiStrSize (BestPlatformLang);
+        VariableEntry[0].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize 
+ GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);
+        VariableEntry[0].VariableSize = HEADER_ALIGN 
(VariableEntry[0].VariableSize);
+        VariableEntry[0].Guid = &gEfiGlobalVariableGuid;
+        VariableEntry[0].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;
+        //
+        // Calculate the needed variable size for Lang variable.
+        //
+        VarNameSize = StrSize (EFI_LANG_VARIABLE_NAME);
+        VarDataSize = ISO_639_2_ENTRY_SIZE + 1;
+        VariableEntry[1].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize 
+ GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);
+        VariableEntry[1].VariableSize = HEADER_ALIGN 
(VariableEntry[1].VariableSize);
+        VariableEntry[1].Guid = &gEfiGlobalVariableGuid;
+        VariableEntry[1].Name = EFI_LANG_VARIABLE_NAME;
+        if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, 
&VariableEntry[0], &VariableEntry[1], NULL)) {
+          //
+          // No enough variable space to set both PlatformLang and Lang 
successfully.
+          //
+          Status = EFI_OUT_OF_RESOURCES;
+        } else {
+          //
+          // Successfully convert Lang to PlatformLang, and set the 
BestPlatformLang value into PlatformLang variable simultaneously.
+          //
+          FindVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, 
&gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, 
FALSE);
 
-        Status = UpdateVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, 
&gEfiGlobalVariableGuid, BestPlatformLang, 
-                                 AsciiStrSize (BestPlatformLang), Attributes, 
&Variable);
+          Status = UpdateVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, 
&gEfiGlobalVariableGuid, BestPlatformLang, 
+                                   AsciiStrSize (BestPlatformLang), 
Attributes, &Variable);
+        }
 
         DEBUG ((EFI_D_INFO, "Variable Driver Auto Update Lang, Lang:%a, 
PlatformLang:%a Status: %r\n", BestLang, BestPlatformLang, Status));
       }
     }
   }
 
-  return Status;
+  if (SetLanguageCodes) {
+    //
+    // Continue to set PlatformLangCodes or LangCodes.
+    //
+    return EFI_SUCCESS;
+  } else {
+    return Status;
+  }
 }
 
 /**
@@ -2492,15 +2667,17 @@
     }
   }
 
-  //
-  // Hook the operation of setting PlatformLangCodes/PlatformLang and 
LangCodes/Lang.
-  //
-  Status = AutoUpdateLangVariable (VariableName, Data, DataSize);
-  if (EFI_ERROR (Status)) {
+  if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
     //
-    // The auto update operation failed, directly return to avoid 
inconsistency between PlatformLang and Lang.
+    // Hook the operation of setting PlatformLangCodes/PlatformLang and 
LangCodes/Lang.
     //
-    goto Done;
+    Status = AutoUpdateLangVariable (VariableName, Data, DataSize);
+    if (EFI_ERROR (Status)) {
+      //
+      // The auto update operation failed, directly return to avoid 
inconsistency between PlatformLang and Lang.
+      //
+      goto Done;
+    }
   }
 
   Status = UpdateVariable (VariableName, VendorGuid, Data, DataSize, 
Attributes, &Variable);
@@ -2525,14 +2702,12 @@
   @param MaximumVariableSize            Pointer to the maximum size of an 
individual EFI variables
                                         associated with the attributes 
specified.
 
-  @return EFI_INVALID_PARAMETER         An invalid combination of attribute 
bits was supplied.
   @return EFI_SUCCESS                   Query successfully.
-  @return EFI_UNSUPPORTED               The attribute is not supported on this 
platform.
 
 **/
 EFI_STATUS
 EFIAPI
-VariableServiceQueryVariableInfo (
+VariableServiceQueryVariableInfoInternal (
   IN  UINT32                 Attributes,
   OUT UINT64                 *MaximumVariableStorageSize,
   OUT UINT64                 *RemainingVariableStorageSize,
@@ -2545,43 +2720,12 @@
   VARIABLE_STORE_HEADER  *VariableStoreHeader;
   UINT64                 CommonVariableTotalSize;
   UINT64                 HwErrVariableTotalSize;
+  EFI_STATUS             Status;
+  VARIABLE_POINTER_TRACK VariablePtrTrack;
 
   CommonVariableTotalSize = 0;
   HwErrVariableTotalSize = 0;
 
-  if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == 
NULL || MaximumVariableSize == NULL || Attributes == 0) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if((Attributes & (EFI_VARIABLE_NON_VOLATILE | 
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | 
EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == 0) {
-    //
-    // Make sure the Attributes combination is supported by the platform.
-    //
-    return EFI_UNSUPPORTED;  
-  } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | 
EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {
-    //
-    // Make sure if runtime bit is set, boot service bit is set also.
-    //
-    return EFI_INVALID_PARAMETER;
-  } else if (AtRuntime () && ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 
0)) {
-    //
-    // Make sure RT Attribute is set if we are in Runtime phase.
-    //
-    return EFI_INVALID_PARAMETER;
-  } else if ((Attributes & (EFI_VARIABLE_NON_VOLATILE | 
EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
-    //
-    // Make sure Hw Attribute is set with NV.
-    //
-    return EFI_INVALID_PARAMETER;
-  } else if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {
-    //
-    // Not support authentiated variable write yet.
-    //
-    return EFI_UNSUPPORTED;
-  }
-
-  
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
-
   if((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {
     //
     // Query is Volatile related.
@@ -2653,6 +2797,27 @@
         } else {
           CommonVariableTotalSize += VariableSize;
         }
+      } else if (Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
+        //
+        // If it is a IN_DELETED_TRANSITION variable,
+        // and there is not also a same ADDED one at the same time,
+        // this IN_DELETED_TRANSITION variable is valid.
+        //
+        VariablePtrTrack.StartPtr = GetStartPointer (VariableStoreHeader);
+        VariablePtrTrack.EndPtr   = GetEndPointer   (VariableStoreHeader);
+        Status = FindVariableEx (
+                   GetVariableNamePtr (Variable),
+                   &Variable->VendorGuid,
+                   FALSE,
+                   &VariablePtrTrack
+                   );
+        if (!EFI_ERROR (Status) && VariablePtrTrack.CurrPtr->State != 
VAR_ADDED) {
+          if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 
EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+            HwErrVariableTotalSize += VariableSize;
+          } else {
+            CommonVariableTotalSize += VariableSize;
+          }
+        }
       }
     }
 
@@ -2674,11 +2839,82 @@
     *MaximumVariableSize = *RemainingVariableStorageSize - sizeof 
(VARIABLE_HEADER);
   }
 
-  ReleaseLockOnlyAtBootTime 
(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
   return EFI_SUCCESS;
 }
 
+/**
 
+  This code returns information about the EFI variables.
+
+  @param Attributes                     Attributes bitmask to specify the type 
of variables
+                                        on which to return information.
+  @param MaximumVariableStorageSize     Pointer to the maximum size of the 
storage space available
+                                        for the EFI variables associated with 
the attributes specified.
+  @param RemainingVariableStorageSize   Pointer to the remaining size of the 
storage space available
+                                        for EFI variables associated with the 
attributes specified.
+  @param MaximumVariableSize            Pointer to the maximum size of an 
individual EFI variables
+                                        associated with the attributes 
specified.
+
+  @return EFI_INVALID_PARAMETER         An invalid combination of attribute 
bits was supplied.
+  @return EFI_SUCCESS                   Query successfully.
+  @return EFI_UNSUPPORTED               The attribute is not supported on this 
platform.
+
+**/
+EFI_STATUS
+EFIAPI
+VariableServiceQueryVariableInfo (
+  IN  UINT32                 Attributes,
+  OUT UINT64                 *MaximumVariableStorageSize,
+  OUT UINT64                 *RemainingVariableStorageSize,
+  OUT UINT64                 *MaximumVariableSize
+  )
+{
+  EFI_STATUS             Status;
+
+  if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == 
NULL || MaximumVariableSize == NULL || Attributes == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if((Attributes & (EFI_VARIABLE_NON_VOLATILE | 
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | 
EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == 0) {
+    //
+    // Make sure the Attributes combination is supported by the platform.
+    //
+    return EFI_UNSUPPORTED;
+  } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | 
EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {
+    //
+    // Make sure if runtime bit is set, boot service bit is set also.
+    //
+    return EFI_INVALID_PARAMETER;
+  } else if (AtRuntime () && ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 
0)) {
+    //
+    // Make sure RT Attribute is set if we are in Runtime phase.
+    //
+    return EFI_INVALID_PARAMETER;
+  } else if ((Attributes & (EFI_VARIABLE_NON_VOLATILE | 
EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+    //
+    // Make sure Hw Attribute is set with NV.
+    //
+    return EFI_INVALID_PARAMETER;
+  } else if ((Attributes & (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | 
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | 
EFI_VARIABLE_APPEND_WRITE)) != 0) {
+    //
+    // Not support authenticated or append variable write yet.
+    //
+    return EFI_UNSUPPORTED;
+  }
+
+  
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+
+  Status = VariableServiceQueryVariableInfoInternal (
+             Attributes,
+             MaximumVariableStorageSize,
+             RemainingVariableStorageSize,
+             MaximumVariableSize
+             );
+
+  ReleaseLockOnlyAtBootTime 
(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+  return Status;
+}
+
 /**
   This function reclaims variable storage if free size is below the threshold.
   

Modified: trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
===================================================================
--- trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h    
2014-03-25 05:04:21 UTC (rev 15387)
+++ trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h    
2014-03-25 06:56:55 UTC (rev 15388)
@@ -3,7 +3,7 @@
   The internal header file includes the common header files, defines
   internal structure and functions used by Variable modules.
 
-Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD 
License
 which accompanies this distribution.  The full text of the license may be 
found at
@@ -101,10 +101,12 @@
 typedef struct {
   EFI_GUID    *Guid;
   CHAR16      *Name;
-  UINT32      Attributes;
-  UINTN       DataSize;
-  VOID        *Data;
-} VARIABLE_CACHE_ENTRY;
+//  UINT32      Attributes;
+  //
+  // Variable size include variable header, name and data.
+  //
+  UINTN       VariableSize;
+} VARIABLE_ENTRY_CONSISTENCY;
 
 typedef struct {
   EFI_GUID    Guid;
@@ -456,6 +458,31 @@
   @param MaximumVariableSize            Pointer to the maximum size of an 
individual EFI variables
                                         associated with the attributes 
specified.
 
+  @return EFI_SUCCESS                   Query successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+VariableServiceQueryVariableInfoInternal (
+  IN  UINT32                 Attributes,
+  OUT UINT64                 *MaximumVariableStorageSize,
+  OUT UINT64                 *RemainingVariableStorageSize,
+  OUT UINT64                 *MaximumVariableSize
+  );
+
+/**
+
+  This code returns information about the EFI variables.
+
+  @param Attributes                     Attributes bitmask to specify the type 
of variables
+                                        on which to return information.
+  @param MaximumVariableStorageSize     Pointer to the maximum size of the 
storage space available
+                                        for the EFI variables associated with 
the attributes specified.
+  @param RemainingVariableStorageSize   Pointer to the remaining size of the 
storage space available
+                                        for EFI variables associated with the 
attributes specified.
+  @param MaximumVariableSize            Pointer to the maximum size of an 
individual EFI variables
+                                        associated with the attributes 
specified.
+
   @return EFI_INVALID_PARAMETER         An invalid combination of attribute 
bits was supplied.
   @return EFI_SUCCESS                   Query successfully.
   @return EFI_UNSUPPORTED               The attribute is not supported on this 
platform.

Modified: 
trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
===================================================================
--- 
trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf    
    2014-03-25 05:04:21 UTC (rev 15387)
+++ 
trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf    
    2014-03-25 06:56:55 UTC (rev 15388)
@@ -2,7 +2,7 @@
 # Component description file for Variable module.
 #
 # This module installs three EFI_RUNTIME_SERVICES: SetVariable, GetVariable, 
GetNextVariableName.
-# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD 
License
@@ -80,7 +80,8 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize
   
 [FeaturePcd]
-  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics  ## 
SOMETIME_CONSUMES (statistic the information of variable.)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics  ## CONSUMES # 
statistic the information of variable.
+  gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES
 
 [Depex]
   TRUE

Modified: trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
===================================================================
--- trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf       
2014-03-25 05:04:21 UTC (rev 15387)
+++ trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf       
2014-03-25 06:56:55 UTC (rev 15388)
@@ -14,7 +14,7 @@
 #  This external input must be validated carefully to avoid security issue like
 #  buffer overflow, integer overflow.
 #
-# Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
 # This program and the accompanying materials
 # are licensed and made available under the terms and conditions of the BSD 
License
 # which accompanies this distribution. The full text of the license may be 
found at
@@ -89,7 +89,8 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize
   
 [FeaturePcd]
-  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics  ## 
SOMETIME_CONSUMES (statistic the information of variable.)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics  ## CONSUMES # 
statistic the information of variable.
+  gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES
 
 [Depex]
   TRUE

Modified: trunk/edk2/MdePkg/MdePkg.dec
===================================================================
--- trunk/edk2/MdePkg/MdePkg.dec        2014-03-25 05:04:21 UTC (rev 15387)
+++ trunk/edk2/MdePkg/MdePkg.dec        2014-03-25 06:56:55 UTC (rev 15388)
@@ -1375,7 +1375,8 @@
   ## If TRUE, the driver diagnostics2 protocol will not be installed.
   
gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|FALSE|BOOLEAN|0x00000011
 
-  ## Indicates whether EFI 1.1 ISO 639-2 language supports are obsolete
+  ## Indicates whether EFI 1.1 ISO 639-2 language supports are obsolete.
+  #  If TRUE, Variable driver will be also not to auto update between 
PlatformLang and Lang variables.
   
gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate|FALSE|BOOLEAN|0x00000012
 
   ## If TRUE, UGA Draw Protocol is still consumed.

Modified: trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
===================================================================
--- trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c  
2014-03-25 05:04:21 UTC (rev 15387)
+++ trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c  
2014-03-25 06:56:55 UTC (rev 15388)
@@ -1509,6 +1509,121 @@
 }
 
 /**
+  This function is to check if the remaining variable space is enough to set
+  all Variables from argument list successfully. The purpose of the check
+  is to keep the consistency of the Variables to be in variable storage.
+
+  Note: Variables are assumed to be in same storage.
+  The set sequence of Variables will be same with the sequence of 
VariableEntry from argument list,
+  so follow the argument sequence to check the Variables.
+
+  @param[in] Attributes         Variable attributes for Variable entries.
+  @param     ...                Variable argument list with type 
VARIABLE_ENTRY_CONSISTENCY *.
+                                A NULL terminates the list.
+
+  @retval TRUE                  Have enough variable space to set the 
Variables successfully.
+  @retval FALSE                 No enough variable space to set the Variables 
successfully.
+
+**/
+BOOLEAN
+EFIAPI
+CheckRemainingSpaceForConsistency (
+  IN UINT32                     Attributes,
+  ...
+  )
+{
+  EFI_STATUS                    Status;
+  VA_LIST                       Args;
+  VARIABLE_ENTRY_CONSISTENCY    *VariableEntry;
+  UINT64                        MaximumVariableStorageSize;
+  UINT64                        RemainingVariableStorageSize;
+  UINT64                        MaximumVariableSize;
+  UINTN                         TotalNeededSize;
+  UINTN                         OriginalVarSize;
+  VARIABLE_STORE_HEADER         *VariableStoreHeader;
+  VARIABLE_POINTER_TRACK        VariablePtrTrack;
+  VARIABLE_HEADER               *NextVariable;
+
+  //
+  // Non-Volatile related.
+  //
+  VariableStoreHeader = mNvVariableCache;
+
+  Status = VariableServiceQueryVariableInfoInternal (
+             Attributes,
+             &MaximumVariableStorageSize,
+             &RemainingVariableStorageSize,
+             &MaximumVariableSize
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  TotalNeededSize = 0;
+  VA_START (Args, Attributes);
+  VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+  while (VariableEntry != NULL) {
+    TotalNeededSize += VariableEntry->VariableSize;
+    VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+  }
+  VA_END (Args);
+
+  if (RemainingVariableStorageSize >= TotalNeededSize) {
+    //
+    // Already have enough space.
+    //
+    return TRUE;
+  } else if (AtRuntime ()) {
+    //
+    // At runtime, no reclaim.
+    // The original variable space of Variables can't be reused.
+    //
+    return FALSE;
+  }
+
+  VA_START (Args, Attributes);
+  VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+  while (VariableEntry != NULL) {
+    //
+    // Check if Variable[Index] has been present and get its size.
+    //
+    OriginalVarSize = 0;
+    VariablePtrTrack.StartPtr = GetStartPointer (VariableStoreHeader);
+    VariablePtrTrack.EndPtr   = GetEndPointer   (VariableStoreHeader);
+    Status = FindVariableEx (
+               VariableEntry->Name,
+               VariableEntry->Guid,
+               FALSE,
+               &VariablePtrTrack
+               );
+    if (!EFI_ERROR (Status)) {
+      //
+      // Get size of Variable[Index].
+      //
+      NextVariable = GetNextVariablePtr (VariablePtrTrack.CurrPtr);
+      OriginalVarSize = (UINTN) NextVariable - (UINTN) 
VariablePtrTrack.CurrPtr;
+      //
+      // Add the original size of Variable[Index] to remaining variable 
storage size.
+      //
+      RemainingVariableStorageSize += OriginalVarSize;
+    }
+    if (VariableEntry->VariableSize > RemainingVariableStorageSize) {
+      //
+      // No enough space for Variable[Index].
+      //
+      VA_END (Args);
+      return FALSE;
+    }
+    //
+    // Sub the (new) size of Variable[Index] from remaining variable storage 
size.
+    //
+    RemainingVariableStorageSize -= VariableEntry->VariableSize;
+    VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+  }
+  VA_END (Args);
+
+  return TRUE;
+}
+
+/**
   Hook the operations in PlatformLangCodes, LangCodes, PlatformLang and Lang.
 
   When setting Lang/LangCodes, simultaneously update 
PlatformLang/PlatformLangCodes.
@@ -1542,6 +1657,9 @@
   UINT32                 Attributes;
   VARIABLE_POINTER_TRACK Variable;
   BOOLEAN                SetLanguageCodes;
+  UINTN                  VarNameSize;
+  UINTN                  VarDataSize;
+  VARIABLE_ENTRY_CONSISTENCY VariableEntry[2];
 
   //
   // Don't do updates for delete operation
@@ -1664,12 +1782,37 @@
         BestLang = GetLangFromSupportedLangCodes 
(mVariableModuleGlobal->LangCodes, Index, TRUE);
 
         //
-        // Successfully convert PlatformLang to Lang, and set the BestLang 
value into Lang variable simultaneously.
+        // Calculate the needed variable size for Lang variable.
         //
-        FindVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, 
&Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
+        VarNameSize = StrSize (EFI_LANG_VARIABLE_NAME);
+        VarDataSize = ISO_639_2_ENTRY_SIZE + 1;
+        VariableEntry[0].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize 
+ GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);
+        VariableEntry[0].VariableSize = HEADER_ALIGN 
(VariableEntry[0].VariableSize);
+        VariableEntry[0].Guid = &gEfiGlobalVariableGuid;
+        VariableEntry[0].Name = EFI_LANG_VARIABLE_NAME;
+        //
+        // Calculate the needed variable size for PlatformLang variable.
+        //
+        VarNameSize = StrSize (EFI_PLATFORM_LANG_VARIABLE_NAME);
+        VarDataSize = AsciiStrSize (BestPlatformLang);
+        VariableEntry[1].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize 
+ GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);
+        VariableEntry[1].VariableSize = HEADER_ALIGN 
(VariableEntry[1].VariableSize);
+        VariableEntry[1].Guid = &gEfiGlobalVariableGuid;
+        VariableEntry[1].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;
+        if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, 
&VariableEntry[0], &VariableEntry[1], NULL)) {
+          //
+          // No enough variable space to set both Lang and PlatformLang 
successfully.
+          //
+          Status = EFI_OUT_OF_RESOURCES;
+        } else {
+          //
+          // Successfully convert PlatformLang to Lang, and set the BestLang 
value into Lang variable simultaneously.
+          //
+          FindVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, 
&Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
 
-        Status = UpdateVariable (EFI_LANG_VARIABLE_NAME, 
&gEfiGlobalVariableGuid, BestLang,
-                                 ISO_639_2_ENTRY_SIZE + 1, Attributes, 0, 0, 
&Variable, NULL);
+          Status = UpdateVariable (EFI_LANG_VARIABLE_NAME, 
&gEfiGlobalVariableGuid, BestLang,
+                                   ISO_639_2_ENTRY_SIZE + 1, Attributes, 0, 0, 
&Variable, NULL);
+        }
 
         DEBUG ((EFI_D_INFO, "Variable Driver Auto Update PlatformLang, 
PlatformLang:%a, Lang:%a Status: %r\n", BestPlatformLang, BestLang, Status));
       }
@@ -1696,19 +1839,51 @@
         BestPlatformLang = GetLangFromSupportedLangCodes 
(mVariableModuleGlobal->PlatformLangCodes, Index, FALSE);
 
         //
-        // Successfully convert Lang to PlatformLang, and set the 
BestPlatformLang value into PlatformLang variable simultaneously.
+        // Calculate the needed variable size for PlatformLang variable.
         //
-        FindVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, 
&gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, 
FALSE);
+        VarNameSize = StrSize (EFI_PLATFORM_LANG_VARIABLE_NAME);
+        VarDataSize = AsciiStrSize (BestPlatformLang);
+        VariableEntry[0].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize 
+ GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);
+        VariableEntry[0].VariableSize = HEADER_ALIGN 
(VariableEntry[0].VariableSize);
+        VariableEntry[0].Guid = &gEfiGlobalVariableGuid;
+        VariableEntry[0].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;
+        //
+        // Calculate the needed variable size for Lang variable.
+        //
+        VarNameSize = StrSize (EFI_LANG_VARIABLE_NAME);
+        VarDataSize = ISO_639_2_ENTRY_SIZE + 1;
+        VariableEntry[1].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize 
+ GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);
+        VariableEntry[1].VariableSize = HEADER_ALIGN 
(VariableEntry[1].VariableSize);
+        VariableEntry[1].Guid = &gEfiGlobalVariableGuid;
+        VariableEntry[1].Name = EFI_LANG_VARIABLE_NAME;
+        if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, 
&VariableEntry[0], &VariableEntry[1], NULL)) {
+          //
+          // No enough variable space to set both PlatformLang and Lang 
successfully.
+          //
+          Status = EFI_OUT_OF_RESOURCES;
+        } else {
+          //
+          // Successfully convert Lang to PlatformLang, and set the 
BestPlatformLang value into PlatformLang variable simultaneously.
+          //
+          FindVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, 
&gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, 
FALSE);
 
-        Status = UpdateVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, 
&gEfiGlobalVariableGuid, BestPlatformLang,
-                                 AsciiStrSize (BestPlatformLang), Attributes, 
0, 0, &Variable, NULL);
+          Status = UpdateVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, 
&gEfiGlobalVariableGuid, BestPlatformLang,
+                                   AsciiStrSize (BestPlatformLang), 
Attributes, 0, 0, &Variable, NULL);
+        }
 
         DEBUG ((EFI_D_INFO, "Variable Driver Auto Update Lang, Lang:%a, 
PlatformLang:%a Status: %r\n", BestLang, BestPlatformLang, Status));
       }
     }
   }
 
-  return Status;
+  if (SetLanguageCodes) {
+    //
+    // Continue to set PlatformLangCodes or LangCodes.
+    //
+    return EFI_SUCCESS;
+  } else {
+    return Status;
+  }
 }
 
 /**
@@ -2992,16 +3167,18 @@
       goto Done;
     }
   }
-  
-  //
-  // Hook the operation of setting PlatformLangCodes/PlatformLang and 
LangCodes/Lang.
-  //
-  Status = AutoUpdateLangVariable (VariableName, Data, DataSize);
-  if (EFI_ERROR (Status)) {
+
+  if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
     //
-    // The auto update operation failed, directly return to avoid 
inconsistency between PlatformLang and Lang.
+    // Hook the operation of setting PlatformLangCodes/PlatformLang and 
LangCodes/Lang.
     //
-    goto Done;
+    Status = AutoUpdateLangVariable (VariableName, Data, DataSize);
+    if (EFI_ERROR (Status)) {
+      //
+      // The auto update operation failed, directly return to avoid 
inconsistency between PlatformLang and Lang.
+      //
+      goto Done;
+    }
   }
 
   //
@@ -3053,14 +3230,12 @@
   @param MaximumVariableSize            Pointer to the maximum size of an 
individual EFI variables
                                         associated with the attributes 
specified.
 
-  @return EFI_INVALID_PARAMETER         An invalid combination of attribute 
bits was supplied.
   @return EFI_SUCCESS                   Query successfully.
-  @return EFI_UNSUPPORTED               The attribute is not supported on this 
platform.
 
 **/
 EFI_STATUS
 EFIAPI
-VariableServiceQueryVariableInfo (
+VariableServiceQueryVariableInfoInternal (
   IN  UINT32                 Attributes,
   OUT UINT64                 *MaximumVariableStorageSize,
   OUT UINT64                 *RemainingVariableStorageSize,
@@ -3073,38 +3248,12 @@
   VARIABLE_STORE_HEADER  *VariableStoreHeader;
   UINT64                 CommonVariableTotalSize;
   UINT64                 HwErrVariableTotalSize;
+  EFI_STATUS             Status;
+  VARIABLE_POINTER_TRACK VariablePtrTrack;
 
   CommonVariableTotalSize = 0;
   HwErrVariableTotalSize = 0;
 
-  if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == 
NULL || MaximumVariableSize == NULL || Attributes == 0) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if((Attributes & (EFI_VARIABLE_NON_VOLATILE | 
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | 
EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == 0) {
-    //
-    // Make sure the Attributes combination is supported by the platform.
-    //
-    return EFI_UNSUPPORTED;
-  } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | 
EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {
-    //
-    // Make sure if runtime bit is set, boot service bit is set also.
-    //
-    return EFI_INVALID_PARAMETER;
-  } else if (AtRuntime () && ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 
0)) {
-    //
-    // Make sure RT Attribute is set if we are in Runtime phase.
-    //
-    return EFI_INVALID_PARAMETER;
-  } else if ((Attributes & (EFI_VARIABLE_NON_VOLATILE | 
EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
-    //
-    // Make sure Hw Attribute is set with NV.
-    //
-    return EFI_INVALID_PARAMETER;
-  }
-
-  
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
-
   if((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {
     //
     // Query is Volatile related.
@@ -3176,6 +3325,27 @@
         } else {
           CommonVariableTotalSize += VariableSize;
         }
+      } else if (Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
+        //
+        // If it is a IN_DELETED_TRANSITION variable,
+        // and there is not also a same ADDED one at the same time,
+        // this IN_DELETED_TRANSITION variable is valid.
+        //
+        VariablePtrTrack.StartPtr = GetStartPointer (VariableStoreHeader);
+        VariablePtrTrack.EndPtr   = GetEndPointer   (VariableStoreHeader);
+        Status = FindVariableEx (
+                   GetVariableNamePtr (Variable),
+                   &Variable->VendorGuid,
+                   FALSE,
+                   &VariablePtrTrack
+                   );
+        if (!EFI_ERROR (Status) && VariablePtrTrack.CurrPtr->State != 
VAR_ADDED) {
+          if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 
EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+            HwErrVariableTotalSize += VariableSize;
+          } else {
+            CommonVariableTotalSize += VariableSize;
+          }
+        }
       }
     }
 
@@ -3197,11 +3367,80 @@
     *MaximumVariableSize = *RemainingVariableStorageSize - sizeof 
(VARIABLE_HEADER);
   }
 
-  ReleaseLockOnlyAtBootTime 
(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
   return EFI_SUCCESS;
 }
 
+/**
 
+  This code returns information about the EFI variables.
+
+  Caution: This function may receive untrusted input.
+  This function may be invoked in SMM mode. This function will do basic 
validation, before parse the data.
+
+  @param Attributes                     Attributes bitmask to specify the type 
of variables
+                                        on which to return information.
+  @param MaximumVariableStorageSize     Pointer to the maximum size of the 
storage space available
+                                        for the EFI variables associated with 
the attributes specified.
+  @param RemainingVariableStorageSize   Pointer to the remaining size of the 
storage space available
+                                        for EFI variables associated with the 
attributes specified.
+  @param MaximumVariableSize            Pointer to the maximum size of an 
individual EFI variables
+                                        associated with the attributes 
specified.
+
+  @return EFI_INVALID_PARAMETER         An invalid combination of attribute 
bits was supplied.
+  @return EFI_SUCCESS                   Query successfully.
+  @return EFI_UNSUPPORTED               The attribute is not supported on this 
platform.
+
+**/
+EFI_STATUS
+EFIAPI
+VariableServiceQueryVariableInfo (
+  IN  UINT32                 Attributes,
+  OUT UINT64                 *MaximumVariableStorageSize,
+  OUT UINT64                 *RemainingVariableStorageSize,
+  OUT UINT64                 *MaximumVariableSize
+  )
+{
+  EFI_STATUS             Status;
+
+  if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == 
NULL || MaximumVariableSize == NULL || Attributes == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if((Attributes & (EFI_VARIABLE_NON_VOLATILE | 
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | 
EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == 0) {
+    //
+    // Make sure the Attributes combination is supported by the platform.
+    //
+    return EFI_UNSUPPORTED;
+  } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | 
EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {
+    //
+    // Make sure if runtime bit is set, boot service bit is set also.
+    //
+    return EFI_INVALID_PARAMETER;
+  } else if (AtRuntime () && ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 
0)) {
+    //
+    // Make sure RT Attribute is set if we are in Runtime phase.
+    //
+    return EFI_INVALID_PARAMETER;
+  } else if ((Attributes & (EFI_VARIABLE_NON_VOLATILE | 
EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+    //
+    // Make sure Hw Attribute is set with NV.
+    //
+    return EFI_INVALID_PARAMETER;
+  }
+
+  
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+
+  Status = VariableServiceQueryVariableInfoInternal (
+             Attributes,
+             MaximumVariableStorageSize,
+             RemainingVariableStorageSize,
+             MaximumVariableSize
+             );
+
+  ReleaseLockOnlyAtBootTime 
(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+  return Status;
+}
+
 /**
   This function reclaims variable storage if free size is below the threshold.
 

Modified: trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h
===================================================================
--- trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h  
2014-03-25 05:04:21 UTC (rev 15387)
+++ trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h  
2014-03-25 06:56:55 UTC (rev 15388)
@@ -2,7 +2,7 @@
   The internal header file includes the common header files, defines
   internal structure and functions used by Variable modules.
 
-Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials 
 are licensed and made available under the terms and conditions of the BSD 
License 
 which accompanies this distribution.  The full text of the license may be 
found at 
@@ -111,10 +111,12 @@
 typedef struct {
   EFI_GUID    *Guid;
   CHAR16      *Name;
-  UINT32      Attributes;
-  UINTN       DataSize;
-  VOID        *Data;
-} VARIABLE_CACHE_ENTRY;
+//  UINT32      Attributes;
+  //
+  // Variable size include variable header, name and data.
+  //
+  UINTN       VariableSize;
+} VARIABLE_ENTRY_CONSISTENCY;
 
 typedef struct {
   EFI_GUID    Guid;
@@ -580,6 +582,34 @@
   @param MaximumVariableSize            Pointer to the maximum size of an 
individual EFI variables
                                         associated with the attributes 
specified.
 
+  @return EFI_SUCCESS                   Query successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+VariableServiceQueryVariableInfoInternal (
+  IN  UINT32                 Attributes,
+  OUT UINT64                 *MaximumVariableStorageSize,
+  OUT UINT64                 *RemainingVariableStorageSize,
+  OUT UINT64                 *MaximumVariableSize
+  );
+
+/**
+
+  This code returns information about the EFI variables.
+
+  Caution: This function may receive untrusted input.
+  This function may be invoked in SMM mode. This function will do basic 
validation, before parse the data.
+
+  @param Attributes                     Attributes bitmask to specify the type 
of variables
+                                        on which to return information.
+  @param MaximumVariableStorageSize     Pointer to the maximum size of the 
storage space available
+                                        for the EFI variables associated with 
the attributes specified.
+  @param RemainingVariableStorageSize   Pointer to the remaining size of the 
storage space available
+                                        for EFI variables associated with the 
attributes specified.
+  @param MaximumVariableSize            Pointer to the maximum size of an 
individual EFI variables
+                                        associated with the attributes 
specified.
+
   @return EFI_INVALID_PARAMETER         An invalid combination of attribute 
bits was supplied.
   @return EFI_SUCCESS                   Query successfully.
   @return EFI_UNSUPPORTED               The attribute is not supported on this 
platform.

Modified: 
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf
===================================================================
--- 
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf  
    2014-03-25 05:04:21 UTC (rev 15387)
+++ 
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf  
    2014-03-25 06:56:55 UTC (rev 15388)
@@ -99,7 +99,8 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize
 
 [FeaturePcd]
-  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics  ## 
SOMETIME_CONSUMES (statistic the information of variable.)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics  ## CONSUMES # 
statistic the information of variable.
+  gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES
 
 [Depex]
   TRUE

Modified: 
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf
===================================================================
--- trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf     
2014-03-25 05:04:21 UTC (rev 15387)
+++ trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf     
2014-03-25 06:56:55 UTC (rev 15388)
@@ -102,7 +102,8 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize
 
 [FeaturePcd]
-  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics  ## 
SOMETIME_CONSUMES (statistic the information of variable.)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics  ## CONSUMES # 
statistic the information of variable.
+  gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES
 
 [Depex]
   TRUE

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their
applications. Written by three acclaimed leaders in the field,
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/13534_NeoTech
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to