]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
Correct copyright year to 2010
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Expression.c
index 46f70b986bb5064ab95907d91f4df0502b7489fa..4bb1950668285d09690a534f122a294cdbd72d4b 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Utility functions for expression evaluation.\r
 \r
-Copyright (c) 2007, Intel Corporation\r
+Copyright (c) 2007 - 2009, Intel Corporation\r
 All rights reserved. This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -12,7 +12,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 **/\r
 \r
-#include "Ui.h"\r
 #include "Setup.h"\r
 \r
 //\r
@@ -30,7 +29,7 @@ EFI_HII_VALUE *mExpressionEvaluationStackPointer = NULL;
 // Unicode collation protocol interface\r
 //\r
 EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollation = NULL;\r
-\r
+EFI_USER_MANAGER_PROTOCOL      *mUserManager = NULL;\r
 \r
 /**\r
   Grow size of the stack.\r
@@ -79,7 +78,7 @@ GrowStack (
     //\r
     // Free The Old Stack\r
     //\r
-    gBS->FreePool (*Stack);\r
+    FreePool (*Stack);\r
   }\r
 \r
   //\r
@@ -421,6 +420,14 @@ IdToQuestion (
 \r
     Question = IdToQuestion2 (Form, QuestionId);\r
     if (Question != NULL) {\r
+      //\r
+      // EFI variable storage may be updated by Callback() asynchronous,\r
+      // to keep synchronous, always reload the Question Value.\r
+      //\r
+      if (Question->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
+        GetQuestionValue (FormSet, Form, Question, FALSE);\r
+      }\r
+\r
       return Question;\r
     }\r
 \r
@@ -504,7 +511,7 @@ InitializeUnicodeCollationProtocol (
 **/\r
 VOID\r
 IfrStrToUpper (\r
-  CHAR16                   *String\r
+  IN CHAR16                   *String\r
   )\r
 {\r
   while (*String != 0) {\r
@@ -611,7 +618,6 @@ IfrToUint (
   EFI_HII_VALUE  Value;\r
   CHAR16         *String;\r
   CHAR16         *StringPtr;\r
-  UINTN          BufferSize;\r
 \r
   Status = PopExpression (&Value);\r
   if (EFI_ERROR (Status)) {\r
@@ -635,14 +641,14 @@ IfrToUint (
       //\r
       // Hex string\r
       //\r
-      BufferSize = sizeof (UINT64);\r
-      Status = HexStringToBuf ((UINT8 *) &Result->Value.u64, &BufferSize, StringPtr + 2, NULL);\r
+      Result->Value.u64 = StrHexToUint64 (String);\r
     } else {\r
       //\r
-      // BUGBUG: Need handle decimal string\r
+      // decimal string\r
       //\r
+      Result->Value.u64 = StrDecimalToUint64 (String);\r
     }\r
-    gBS->FreePool (String);\r
+    FreePool (String);\r
   } else {\r
     CopyMem (Result, &Value, sizeof (EFI_HII_VALUE));\r
   }\r
@@ -696,7 +702,7 @@ IfrCatenate (
     }\r
 \r
     String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
-    if (String== NULL) {\r
+    if (String[Index] == NULL) {\r
       Status = EFI_NOT_FOUND;\r
       goto Done;\r
     }\r
@@ -717,7 +723,7 @@ Done:
   }\r
   if (String[1] != NULL) {\r
     FreePool (String[1]);\r
-  }  \r
+  }\r
   if (StringPtr != NULL) {\r
     FreePool (StringPtr);\r
   }\r
@@ -766,7 +772,7 @@ IfrMatch (
     }\r
 \r
     String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
-    if (String== NULL) {\r
+    if (String [Index] == NULL) {\r
       Status = EFI_NOT_FOUND;\r
       goto Done;\r
     }\r
@@ -781,7 +787,7 @@ Done:
   }\r
   if (String[1] != NULL) {\r
     FreePool (String[1]);\r
-  }  \r
+  }\r
 \r
   return Status;\r
 }\r
@@ -843,7 +849,7 @@ IfrFind (
     }\r
 \r
     String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
-    if (String== NULL) {\r
+    if (String[Index] == NULL) {\r
       Status = EFI_NOT_FOUND;\r
       goto Done;\r
     }\r
@@ -870,7 +876,7 @@ Done:
   }\r
   if (String[1] != NULL) {\r
     FreePool (String[1]);\r
-  }  \r
+  }\r
 \r
   return Status;\r
 }\r
@@ -941,7 +947,7 @@ IfrMid (
   Result->Type = EFI_IFR_TYPE_STRING;\r
   Result->Value.string = NewString (SubString, FormSet->HiiHandle);\r
 \r
-  gBS->FreePool (String);\r
+  FreePool (String);\r
 \r
   return Status;\r
 }\r
@@ -999,7 +1005,7 @@ IfrToken (
     }\r
 \r
     String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
-    if (String== NULL) {\r
+    if (String[Index] == NULL) {\r
       Status = EFI_NOT_FOUND;\r
       goto Done;\r
     }\r
@@ -1044,7 +1050,7 @@ Done:
   }\r
   if (String[1] != NULL) {\r
     FreePool (String[1]);\r
-  }  \r
+  }\r
 \r
   return Status;\r
 }\r
@@ -1104,7 +1110,7 @@ IfrSpan (
     }\r
 \r
     String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
-    if (String== NULL) {\r
+    if (String [Index] == NULL) {\r
       Status = EFI_NOT_FOUND;\r
       goto Done;\r
     }\r
@@ -1152,7 +1158,7 @@ Done:
   }\r
   if (String[1] != NULL) {\r
     FreePool (String[1]);\r
-  }  \r
+  }\r
 \r
   return Status;\r
 }\r
@@ -1263,14 +1269,14 @@ CompareHiiValue (
 \r
     Str2 = GetToken (Value2->Value.string, HiiHandle);\r
     if (Str2 == NULL) {\r
-      gBS->FreePool (Str1);\r
+      FreePool (Str1);\r
       return EFI_INVALID_PARAMETER;\r
     }\r
 \r
     Result = StrCmp (Str1, Str2);\r
 \r
-    gBS->FreePool (Str1);\r
-    gBS->FreePool (Str2);\r
+    FreePool (Str1);\r
+    FreePool (Str2);\r
 \r
     return Result;\r
   }\r
@@ -1290,9 +1296,113 @@ CompareHiiValue (
   return Result;\r
 }\r
 \r
+/**\r
+  Check if current user has the privilege specified by the permissions GUID.\r
+\r
+  @param[in] Guid  A GUID specifying setup access permissions.\r
+\r
+  @retval TRUE     Current user has the privilege.\r
+  @retval FALSE    Current user does not have the privilege.\r
+**/\r
+BOOLEAN\r
+CheckUserPrivilege (\r
+  IN EFI_GUID *Guid\r
+  )\r
+{\r
+  EFI_STATUS                   Status;\r
+  EFI_USER_PROFILE_HANDLE      UserProfileHandle;\r
+  EFI_USER_INFO_HANDLE         UserInfoHandle;\r
+  EFI_USER_INFO                *UserInfo;\r
+  EFI_GUID                     *UserPermissionsGuid;\r
+  UINTN                        UserInfoSize;\r
+  UINTN                        AccessControlDataSize;\r
+  EFI_USER_INFO_ACCESS_CONTROL *AccessControl;\r
+  UINTN                        RemainSize;\r
+\r
+  if (mUserManager == NULL) {\r
+    Status = gBS->LocateProtocol (\r
+                    &gEfiUserManagerProtocolGuid,\r
+                    NULL,\r
+                    (VOID **) &mUserManager\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      ///\r
+      /// If the system does not support user management, then it is assumed that\r
+      /// all users have admin privilege and evaluation of each EFI_IFR_SECURITY\r
+      /// op-code is always TRUE.\r
+      ///\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  Status = mUserManager->Current (mUserManager, &UserProfileHandle);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  ///\r
+  /// Enumerate all user information of the current user profile\r
+  /// to look for any EFI_USER_INFO_ACCESS_SETUP record.\r
+  ///\r
+  \r
+  for (UserInfoHandle = NULL;;) {\r
+    Status = mUserManager->GetNextInfo (mUserManager, UserProfileHandle, &UserInfoHandle);\r
+    if (EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+\r
+    UserInfoSize = 0;\r
+    Status = mUserManager->GetInfo (mUserManager, UserProfileHandle, UserInfoHandle, NULL, &UserInfoSize);\r
+    if (Status != EFI_BUFFER_TOO_SMALL) {\r
+      continue;\r
+    }\r
+\r
+    UserInfo = (EFI_USER_INFO *) AllocatePool (UserInfoSize);\r
+    if (UserInfo == NULL) {\r
+      break;\r
+    }\r
+\r
+    Status = mUserManager->GetInfo (mUserManager, UserProfileHandle, UserInfoHandle, UserInfo, &UserInfoSize);\r
+    if (EFI_ERROR (Status) ||\r
+        UserInfo->InfoType != EFI_USER_INFO_ACCESS_POLICY_RECORD ||\r
+        UserInfo->InfoSize <= sizeof (EFI_USER_INFO)) {\r
+      FreePool (UserInfo);\r
+      continue;\r
+    }\r
+\r
+    RemainSize = UserInfo->InfoSize - sizeof (EFI_USER_INFO);\r
+    AccessControl = (EFI_USER_INFO_ACCESS_CONTROL *)(UserInfo + 1);\r
+    while (RemainSize >= sizeof (EFI_USER_INFO_ACCESS_CONTROL)) {\r
+      if (RemainSize < AccessControl->Size || AccessControl->Size <= sizeof (EFI_USER_INFO_ACCESS_CONTROL)) {\r
+        break;\r
+      }\r
+      if (AccessControl->Type == EFI_USER_INFO_ACCESS_SETUP) {\r
+        ///\r
+        /// Check if current user has the privilege specified by the permissions GUID.\r
+        ///\r
+\r
+        UserPermissionsGuid = (EFI_GUID *)(AccessControl + 1);\r
+        AccessControlDataSize = AccessControl->Size - sizeof (EFI_USER_INFO_ACCESS_CONTROL);\r
+        while (AccessControlDataSize >= sizeof (EFI_GUID)) {\r
+          if (CompareGuid (Guid, UserPermissionsGuid)) {\r
+            FreePool (UserInfo);\r
+            return TRUE;\r
+          }\r
+          UserPermissionsGuid++;\r
+          AccessControlDataSize -= sizeof (EFI_GUID);\r
+        }\r
+      }\r
+      RemainSize -= AccessControl->Size;\r
+      AccessControl = (EFI_USER_INFO_ACCESS_CONTROL *)((UINT8 *)AccessControl + AccessControl->Size);\r
+    }\r
+\r
+    FreePool (UserInfo);\r
+  }\r
+  return FALSE;\r
+}\r
 \r
 /**\r
-  Evaluate the result of a HII expression\r
+  Evaluate the result of a HII expression.\r
+\r
+  If Expression is NULL, then ASSERT.\r
 \r
   @param  FormSet                FormSet associated with this expression.\r
   @param  Form                   Form associated with this expression.\r
@@ -1334,6 +1444,7 @@ EvaluateExpression (
   //\r
   ResetExpressionStack ();\r
 \r
+  ASSERT (Expression != NULL);\r
   Expression->Result.Type = EFI_IFR_TYPE_OTHER;\r
 \r
   Link = GetFirstNode (&Expression->OpCodeListHead);\r
@@ -1419,6 +1530,10 @@ EvaluateExpression (
       Value = &Question->HiiValue;\r
       break;\r
 \r
+    case EFI_IFR_SECURITY_OP:\r
+      Value->Value.b = CheckUserPrivilege (&OpCode->Guid);\r
+      break;\r
+\r
     case EFI_IFR_QUESTION_REF3_OP:\r
       if (OpCode->DevicePath == 0) {\r
         //\r
@@ -1517,7 +1632,7 @@ EvaluateExpression (
 \r
       Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
       Value->Value.u64 = StrLen (StrPtr);\r
-      gBS->FreePool (StrPtr);\r
+      FreePool (StrPtr);\r
       break;\r
 \r
     case EFI_IFR_NOT_OP:\r
@@ -1581,7 +1696,7 @@ EvaluateExpression (
       } else {\r
         Index = (UINT16) Value->Value.u64;\r
         Value->Value.string = Index;\r
-        gBS->FreePool (StrPtr);\r
+        FreePool (StrPtr);\r
       }\r
       break;\r
 \r
@@ -1621,7 +1736,7 @@ EvaluateExpression (
         } else {\r
           Value->Value.b = FALSE;\r
         }\r
-        gBS->FreePool (StrPtr);\r
+        FreePool (StrPtr);\r
         Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
       }\r
       break;\r
@@ -1661,7 +1776,7 @@ EvaluateExpression (
         mUnicodeCollation->StrUpr (mUnicodeCollation, StrPtr);\r
       }\r
       Value->Value.string = NewString (StrPtr, FormSet->HiiHandle);\r
-      gBS->FreePool (StrPtr);\r
+      FreePool (StrPtr);\r
       break;\r
 \r
     case EFI_IFR_BITWISE_NOT_OP:\r
@@ -1826,7 +1941,7 @@ EvaluateExpression (
         break;\r
 \r
       case EFI_IFR_NOT_EQUAL_OP:\r
-        Value->Value.b = (BOOLEAN) ((Result == 0) ? TRUE : FALSE);\r
+        Value->Value.b = (BOOLEAN) ((Result != 0) ? TRUE : FALSE);\r
         break;\r
 \r
       case EFI_IFR_GREATER_EQUAL_OP:\r