]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Universal/BdsDxe/Hotkey.c
Correct a typo: Change the type of the 4th parameter of EFI_DRIVER_HEALTH_PROTOCOL...
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / Hotkey.c
index d3bb1ef47890b95522de36eb26741d581a1b5c1b..1a3ec1ff844039f000213a09082225a4a68cf6f6 100644 (file)
@@ -64,242 +64,6 @@ IsKeyOptionValid (
   return (BOOLEAN) ((KeyOption->BootOptionCrc == Crc) ? TRUE : FALSE);\r
 }\r
 \r
-/**\r
-  Create Key#### for the given hotkey.\r
-\r
-  @param KeyOption       The Hot Key Option to be added.\r
-  @param KeyOptionNumber The key option number for Key#### (optional).\r
-\r
-  @retval  EFI_SUCCESS            Register hotkey successfully.\r
-  @retval  EFI_INVALID_PARAMETER  The hotkey option is invalid.\r
-  @retval  EFI_OUT_OF_RESOURCES   Fail to allocate memory resource.\r
-\r
-**/\r
-EFI_STATUS\r
-RegisterHotkey (\r
-  IN EFI_KEY_OPTION     *KeyOption,\r
-  OUT UINT16            *KeyOptionNumber\r
-)\r
-{\r
-  UINT16          KeyOptionName[10];\r
-  UINT16          *KeyOrder;\r
-  UINTN           KeyOrderSize;\r
-  UINT16          *NewKeyOrder;\r
-  UINTN           Index;\r
-  UINT16          MaxOptionNumber;\r
-  UINT16          RegisterOptionNumber;\r
-  EFI_KEY_OPTION  *TempOption;\r
-  UINTN           TempOptionSize;\r
-  EFI_STATUS      Status;\r
-  UINTN           KeyOptionSize;\r
-  BOOLEAN         UpdateBootOption;\r
-\r
-  //\r
-  // Validate the given key option\r
-  //\r
-  if (!IsKeyOptionValid (KeyOption)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  KeyOptionSize = sizeof (EFI_KEY_OPTION) + KeyOption->KeyData.Options.InputKeyCount * sizeof (EFI_INPUT_KEY);\r
-  UpdateBootOption = FALSE;\r
-\r
-  //\r
-  // Check whether HotKey conflict with keys used by Setup Browser\r
-  //\r
-  KeyOrder = BdsLibGetVariableAndSize (\r
-               VAR_KEY_ORDER,\r
-               &gEfiGlobalVariableGuid,\r
-               &KeyOrderSize\r
-               );\r
-  if (KeyOrder == NULL) {\r
-    KeyOrderSize = 0;\r
-  }\r
-\r
-  //\r
-  // Find free key option number\r
-  //\r
-  MaxOptionNumber = 0;\r
-  TempOption = NULL;\r
-  for (Index = 0; Index < KeyOrderSize / sizeof (UINT16); Index++) {\r
-    if (MaxOptionNumber < KeyOrder[Index]) {\r
-      MaxOptionNumber = KeyOrder[Index];\r
-    }\r
-\r
-    UnicodeSPrint (KeyOptionName, sizeof (KeyOptionName), L"Key%04x", KeyOrder[Index]);\r
-    TempOption = BdsLibGetVariableAndSize (\r
-                   KeyOptionName,\r
-                   &gEfiGlobalVariableGuid,\r
-                   &TempOptionSize\r
-                   );\r
-    ASSERT (TempOption != NULL);\r
-\r
-    if (CompareMem (TempOption, KeyOption, TempOptionSize) == 0) {\r
-      //\r
-      // Got the option, so just return\r
-      //\r
-      FreePool (TempOption);\r
-      FreePool (KeyOrder);\r
-      return EFI_SUCCESS;\r
-    }\r
-\r
-    if (KeyOption->KeyData.PackedValue == TempOption->KeyData.PackedValue) {\r
-      if (KeyOption->KeyData.Options.InputKeyCount == 0 ||\r
-          CompareMem (\r
-            ((UINT8 *) TempOption) + sizeof (EFI_KEY_OPTION),\r
-            ((UINT8 *) KeyOption) + sizeof (EFI_KEY_OPTION),\r
-            KeyOptionSize - sizeof (EFI_KEY_OPTION)\r
-            ) == 0) {\r
-          //\r
-          // Hotkey is the same but BootOption changed, need update\r
-          //\r
-          UpdateBootOption = TRUE;\r
-          break;\r
-      }\r
-    }\r
-\r
-    FreePool (TempOption);\r
-  }\r
-\r
-  if (UpdateBootOption) {\r
-    RegisterOptionNumber = KeyOrder[Index];\r
-    FreePool (TempOption);\r
-  } else {\r
-    RegisterOptionNumber = (UINT16) (MaxOptionNumber + 1);\r
-  }\r
-\r
-  if (KeyOptionNumber != NULL) {\r
-    *KeyOptionNumber = RegisterOptionNumber;\r
-  }\r
-\r
-  //\r
-  // Create variable Key####\r
-  //\r
-  UnicodeSPrint (KeyOptionName, sizeof (KeyOptionName), L"Key%04x", RegisterOptionNumber);\r
-  Status = gRT->SetVariable (\r
-                  KeyOptionName,\r
-                  &gEfiGlobalVariableGuid,\r
-                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
-                  KeyOptionSize,\r
-                  KeyOption\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    FreePool (KeyOrder);\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Update the key order variable - "KeyOrder"\r
-  //\r
-  if (!UpdateBootOption) {\r
-    Index = KeyOrderSize / sizeof (UINT16);\r
-    KeyOrderSize += sizeof (UINT16);\r
-  }\r
-\r
-  NewKeyOrder = AllocatePool (KeyOrderSize);\r
-  if (NewKeyOrder == NULL) {\r
-    FreePool (KeyOrder);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  if (KeyOrder != NULL) {\r
-    CopyMem (NewKeyOrder, KeyOrder, KeyOrderSize);\r
-  }\r
-\r
-  NewKeyOrder[Index] = RegisterOptionNumber;\r
-\r
-  Status = gRT->SetVariable (\r
-                  VAR_KEY_ORDER,\r
-                  &gEfiGlobalVariableGuid,\r
-                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
-                  KeyOrderSize,\r
-                  NewKeyOrder\r
-                  );\r
-\r
-  FreePool (KeyOrder);\r
-  FreePool (NewKeyOrder);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-\r
-  Delete Key#### for the given Key Option number.\r
-\r
-  @param KeyOptionNumber Key option number for Key####\r
-\r
-  @retval  EFI_SUCCESS            Unregister hotkey successfully.\r
-  @retval  EFI_NOT_FOUND          No Key#### is found for the given Key Option number.\r
-\r
-**/\r
-EFI_STATUS\r
-UnregisterHotkey (\r
-  IN UINT16     KeyOptionNumber\r
-)\r
-{\r
-  UINT16      KeyOption[10];\r
-  UINTN       Index;\r
-  EFI_STATUS  Status;\r
-  UINTN       Index2Del;\r
-  UINT16      *KeyOrder;\r
-  UINTN       KeyOrderSize;\r
-\r
-  //\r
-  // Delete variable Key####\r
-  //\r
-  UnicodeSPrint (KeyOption, sizeof (KeyOption), L"Key%04x", KeyOptionNumber);\r
-  gRT->SetVariable (\r
-         KeyOption,\r
-         &gEfiGlobalVariableGuid,\r
-         EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
-         0,\r
-         NULL\r
-         );\r
-\r
-  //\r
-  // Adjust key order array\r
-  //\r
-  KeyOrder = BdsLibGetVariableAndSize (\r
-               VAR_KEY_ORDER,\r
-               &gEfiGlobalVariableGuid,\r
-               &KeyOrderSize\r
-               );\r
-  if (KeyOrder == NULL) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  Index2Del = 0;\r
-  for (Index = 0; Index < KeyOrderSize / sizeof (UINT16); Index++) {\r
-    if (KeyOrder[Index] == KeyOptionNumber) {\r
-      Index2Del = Index;\r
-      break;\r
-    }\r
-  }\r
-\r
-  if (Index != KeyOrderSize / sizeof (UINT16)) {\r
-    //\r
-    // KeyOptionNumber found in "KeyOrder", delete it\r
-    //\r
-    for (Index = Index2Del; Index < KeyOrderSize / sizeof (UINT16) - 1; Index++) {\r
-      KeyOrder[Index] = KeyOrder[Index + 1];\r
-    }\r
-\r
-    KeyOrderSize -= sizeof (UINT16);\r
-  }\r
-\r
-  Status = gRT->SetVariable (\r
-                  VAR_KEY_ORDER,\r
-                  &gEfiGlobalVariableGuid,\r
-                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
-                  KeyOrderSize,\r
-                  KeyOrder\r
-                  );\r
-\r
-  FreePool (KeyOrder);\r
-\r
-  return Status;\r
-}\r
-\r
 /**\r
   Try to boot the boot option triggered by hotkey.\r
   @retval  EFI_SUCCESS             There is HotkeyBootOption & it is processed\r
@@ -551,7 +315,6 @@ HotkeyInsertList (
   BDS_HOTKEY_OPTION  *HotkeyLeft;\r
   BDS_HOTKEY_OPTION  *HotkeyRight;\r
   UINTN              Index;\r
-  EFI_BOOT_KEY_DATA  KeyOptions;\r
   UINT32             KeyShiftStateLeft;\r
   UINT32             KeyShiftStateRight;\r
   EFI_INPUT_KEY      *InputKey;\r
@@ -564,35 +327,31 @@ HotkeyInsertList (
 \r
   HotkeyLeft->Signature = BDS_HOTKEY_OPTION_SIGNATURE;\r
   HotkeyLeft->BootOptionNumber = KeyOption->BootOption;\r
-\r
-  KeyOptions = KeyOption->KeyData;\r
-\r
-  HotkeyLeft->CodeCount = (UINT8) KeyOptions.Options.InputKeyCount;\r
+  HotkeyLeft->CodeCount = (UINT8) KEY_OPTION_INPUT_KEY_COUNT (KeyOption);\r
 \r
   //\r
   // Map key shift state from KeyOptions to EFI_KEY_DATA.KeyState\r
   //\r
   KeyShiftStateRight = EFI_SHIFT_STATE_VALID;\r
-  if (KeyOptions.Options.ShiftPressed) {\r
+  if (KEY_OPTION_SHIFT_PRESSED (KeyOption)) {\r
     KeyShiftStateRight |= EFI_RIGHT_SHIFT_PRESSED;\r
   }\r
-  if (KeyOptions.Options.ControlPressed) {\r
+  if (KEY_OPTION_CONTROL_PRESSED (KeyOption)) {\r
     KeyShiftStateRight |= EFI_RIGHT_CONTROL_PRESSED;\r
   }\r
-  if (KeyOptions.Options.AltPressed) {\r
+  if (KEY_OPTION_ALT_PRESSED (KeyOption)) {\r
     KeyShiftStateRight |= EFI_RIGHT_ALT_PRESSED;\r
   }\r
-  if (KeyOptions.Options.LogoPressed) {\r
+  if (KEY_OPTION_LOGO_PRESSED (KeyOption)) {\r
     KeyShiftStateRight |= EFI_RIGHT_LOGO_PRESSED;\r
   }\r
-  if (KeyOptions.Options.MenuPressed) {\r
+  if (KEY_OPTION_MENU_PRESSED (KeyOption)) {\r
     KeyShiftStateRight |= EFI_MENU_KEY_PRESSED;\r
   }\r
-  if (KeyOptions.Options.SysReqPressed) {\r
+  if (KEY_OPTION_SYS_REQ_PRESSED (KeyOption)) {\r
     KeyShiftStateRight |= EFI_SYS_REQ_PRESSED;\r
   }\r
 \r
-\r
   KeyShiftStateLeft = (KeyShiftStateRight & 0xffffff00) | ((KeyShiftStateRight & 0xff) << 1);\r
 \r
   InputKey = (EFI_INPUT_KEY *) (((UINT8 *) KeyOption) + sizeof (EFI_KEY_OPTION));\r
@@ -640,12 +399,121 @@ HotkeyInsertList (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Return TRUE when the variable pointed by Name and Guid is a Key#### variable.\r
+\r
+  @param Name         The name of the variable.\r
+  @param Guid         The GUID of the variable.\r
+  @param OptionNumber Return the option number parsed from the Name.\r
+\r
+  @retval TRUE  The variable pointed by Name and Guid is a Key#### variable.\r
+  @retval FALSE The variable pointed by Name and Guid isn't a Key#### variable.\r
+**/\r
+BOOLEAN\r
+IsKeyOptionVariable (\r
+  CHAR16        *Name,\r
+  EFI_GUID      *Guid,\r
+  UINT16        *OptionNumber\r
+  )\r
+{\r
+  UINTN         Index;\r
+  \r
+  if (!CompareGuid (Guid, &gEfiGlobalVariableGuid) ||\r
+      (StrSize (Name) != sizeof (L"Key####")) ||\r
+      (StrnCmp (Name, L"Key", 3) != 0)\r
+     ) {\r
+    return FALSE;\r
+  }\r
+\r
+  *OptionNumber = 0;\r
+  for (Index = 3; Index < 7; Index++) {\r
+    if ((Name[Index] >= L'0') && (Name[Index] <= L'9')) {\r
+      *OptionNumber = *OptionNumber * 10 + Name[Index] - L'0';\r
+    } else if ((Name[Index] >= L'A') && (Name[Index] <= L'F')) {\r
+      *OptionNumber = *OptionNumber * 10 + Name[Index] - L'A';\r
+    } else {\r
+      return FALSE;\r
+    }\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Return an array of key option numbers.\r
+\r
+  @param Count       Return the count of key option numbers.\r
+\r
+  @return UINT16*    Pointer to an array of key option numbers;\r
+**/\r
+UINT16 *\r
+EFIAPI\r
+HotkeyGetOptionNumbers (\r
+  OUT UINTN     *Count\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  UINTN                       Index;\r
+  CHAR16                      *Name;\r
+  EFI_GUID                    Guid;\r
+  UINTN                       NameSize;\r
+  UINTN                       NewNameSize;\r
+  UINT16                      *OptionNumbers;\r
+  UINT16                      OptionNumber;\r
+\r
+  if (Count == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  *Count        = 0;\r
+  OptionNumbers = NULL;\r
+\r
+  NameSize = sizeof (CHAR16);\r
+  Name     = AllocateZeroPool (NameSize);\r
+  ASSERT (Name != NULL);\r
+  while (TRUE) {\r
+    NewNameSize = NameSize;\r
+    Status = gRT->GetNextVariableName (&NewNameSize, Name, &Guid);\r
+    if (Status == EFI_BUFFER_TOO_SMALL) {\r
+      Name = ReallocatePool (NameSize, NewNameSize, Name);\r
+      ASSERT (Name != NULL);\r
+      Status = gRT->GetNextVariableName (&NewNameSize, Name, &Guid);\r
+      NameSize = NewNameSize;\r
+    }\r
+\r
+    if (Status == EFI_NOT_FOUND) {\r
+      break;\r
+    }\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    if (IsKeyOptionVariable (Name ,&Guid, &OptionNumber)) {\r
+      OptionNumbers = ReallocatePool (\r
+                        *Count * sizeof (UINT16),\r
+                        (*Count + 1) * sizeof (UINT16),\r
+                        OptionNumbers\r
+                        );\r
+      ASSERT (OptionNumbers != NULL);\r
+      for (Index = 0; Index < *Count; Index++) {\r
+        if (OptionNumber < OptionNumbers[Index]) {\r
+          break;\r
+        }\r
+      }\r
+      CopyMem (&OptionNumbers[Index + 1], &OptionNumbers[Index], (*Count - Index) * sizeof (UINT16));\r
+      OptionNumbers[Index] = OptionNumber;\r
+      (*Count)++;\r
+    }\r
+  }\r
+\r
+  FreePool (Name);\r
+\r
+  return OptionNumbers;\r
+}\r
+\r
 /**\r
 \r
   Process all the "Key####" variables, associate Hotkeys with corresponding Boot Options.\r
 \r
   @retval  EFI_SUCCESS    Hotkey services successfully initialized.\r
-  @retval  EFI_NOT_FOUND  Can not find the "KeyOrder" variable\r
 **/\r
 EFI_STATUS\r
 InitializeHotkeyService (\r
@@ -654,11 +522,10 @@ InitializeHotkeyService (
 {\r
   EFI_STATUS      Status;\r
   UINT32          BootOptionSupport;\r
-  UINT16          *KeyOrder;\r
-  UINTN           KeyOrderSize;\r
+  UINT16          *KeyOptionNumbers;\r
+  UINTN           KeyOptionCount;\r
   UINTN           Index;\r
-  UINT16          KeyOptionName[8];\r
-  UINTN           KeyOptionSize;\r
+  CHAR16          KeyOptionName[8];\r
   EFI_KEY_OPTION  *KeyOption;\r
 \r
   //\r
@@ -679,33 +546,21 @@ InitializeHotkeyService (
                   sizeof (UINT32),\r
                   &BootOptionSupport\r
                   );\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
-  //\r
-  // Get valid Key Option List from private EFI variable "KeyOrder"\r
-  //\r
-  KeyOrder = BdsLibGetVariableAndSize (\r
-               VAR_KEY_ORDER,\r
-               &gEfiGlobalVariableGuid,\r
-               &KeyOrderSize\r
-               );\r
-\r
-  if (KeyOrder == NULL) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  for (Index = 0; Index < KeyOrderSize / sizeof (UINT16); Index ++) {\r
-    UnicodeSPrint (KeyOptionName, sizeof (KeyOptionName), L"Key%04x", KeyOrder[Index]);\r
-    KeyOption = BdsLibGetVariableAndSize (\r
-                  KeyOptionName,\r
-                  &gEfiGlobalVariableGuid,\r
-                  &KeyOptionSize\r
-                  );\r
-\r
-    if (KeyOption == NULL || !IsKeyOptionValid (KeyOption)) {\r
-      UnregisterHotkey (KeyOrder[Index]);\r
-    } else {\r
+  KeyOptionNumbers = HotkeyGetOptionNumbers (&KeyOptionCount);\r
+  for (Index = 0; Index < KeyOptionCount; Index ++) {\r
+    UnicodeSPrint (KeyOptionName, sizeof (KeyOptionName), L"Key%04x", KeyOptionNumbers[Index]);\r
+    GetEfiGlobalVariable2 (KeyOptionName, (VOID **) &KeyOption, NULL);\r
+    ASSERT (KeyOption != NULL);\r
+    if (IsKeyOptionValid (KeyOption)) {\r
       HotkeyInsertList (KeyOption);\r
     }\r
+    FreePool (KeyOption);\r
+  }\r
+\r
+  if (KeyOptionNumbers != NULL) {\r
+    FreePool (KeyOptionNumbers);\r
   }\r
 \r
   //\r