/** @file
  Hotkey library functions.

Copyright (c) 2011 - 2017, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<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
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "InternalBm.h"

//
// Lock for linked list
//
EFI_LOCK                     mBmHotkeyLock            = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);
LIST_ENTRY                   mBmHotkeyList            = INITIALIZE_LIST_HEAD_VARIABLE (mBmHotkeyList);
EFI_EVENT                    mBmHotkeyTriggered       = NULL;
BOOLEAN                      mBmHotkeyServiceStarted  = FALSE;
UINTN                        mBmHotkeySupportCount    = 0;

//
// Set OptionNumber as unassigned value to indicate the option isn't initialized
//
EFI_BOOT_MANAGER_LOAD_OPTION mBmHotkeyBootOption      = { LoadOptionNumberUnassigned };

EFI_BOOT_MANAGER_KEY_OPTION  *mBmContinueKeyOption    = NULL;
VOID                         *mBmTxtInExRegistration  = NULL;


/**
  Return the buffer size of the EFI_BOOT_MANAGER_KEY_OPTION data.

  @param   KeyOption            The input key option info.

  @retval  The buffer size of the key option data.
**/
UINTN
BmSizeOfKeyOption (
  IN CONST EFI_BOOT_MANAGER_KEY_OPTION  *KeyOption
  )
{
  return OFFSET_OF (EFI_BOOT_MANAGER_KEY_OPTION, Keys)
    + KeyOption->KeyData.Options.InputKeyCount * sizeof (EFI_INPUT_KEY);
}

/**

  Check whether the input key option is valid.

  @param   KeyOption          Key option.
  @param   KeyOptionSize      Size of the key option.

  @retval  TRUE               Input key option is valid.
  @retval  FALSE              Input key option is not valid.
**/
BOOLEAN
BmIsKeyOptionValid (
  IN CONST EFI_BOOT_MANAGER_KEY_OPTION *KeyOption,
  IN       UINTN                       KeyOptionSize
)
{
  UINT16   OptionName[BM_OPTION_NAME_LEN];
  UINT8    *BootOption;
  UINTN    BootOptionSize;
  UINT32   Crc;

  if (BmSizeOfKeyOption (KeyOption) != KeyOptionSize) {
    return FALSE;
  }

  //
  // Check whether corresponding Boot Option exist
  //
  UnicodeSPrint (
    OptionName, sizeof (OptionName), L"%s%04x",
    mBmLoadOptionName[LoadOptionTypeBoot], KeyOption->BootOption
    );
  GetEfiGlobalVariable2 (OptionName, (VOID **) &BootOption, &BootOptionSize);

  if (BootOption == NULL) {
    return FALSE;
  }

  //
  // Check CRC for Boot Option
  //
  gBS->CalculateCrc32 (BootOption, BootOptionSize, &Crc);
  FreePool (BootOption);

  return (BOOLEAN) (KeyOption->BootOptionCrc == Crc);
}

/**

  Check whether the input variable is an key option variable.

  @param   Name               Input variable name.
  @param   Guid               Input variable guid.
  @param   OptionNumber       The option number of this key option variable.

  @retval  TRUE               Input variable is a key option variable.
  @retval  FALSE              Input variable is not a key option variable.
**/
BOOLEAN
BmIsKeyOptionVariable (
  CHAR16        *Name,
  EFI_GUID      *Guid,
  UINT16        *OptionNumber
  )
{
  UINTN         Index;
  UINTN         Uint;
  
  if (!CompareGuid (Guid, &gEfiGlobalVariableGuid) ||
      (StrSize (Name) != sizeof (L"Key####")) ||
      (StrnCmp (Name, L"Key", 3) != 0)
     ) {
    return FALSE;
  }

  *OptionNumber = 0;
  for (Index = 3; Index < 7; Index++) {
    Uint = BmCharToUint (Name[Index]);
    if (Uint == -1) {
      return FALSE;
    } else {
      *OptionNumber = (UINT16) Uint + *OptionNumber * 0x10;
    }
  }

  return TRUE;
}

typedef struct {
  EFI_BOOT_MANAGER_KEY_OPTION *KeyOptions;
  UINTN                       KeyOptionCount;
} BM_COLLECT_KEY_OPTIONS_PARAM;

/**
  Visitor function to collect the key options from NV storage.

  @param Name    Variable name.
  @param Guid    Variable GUID.
  @param Context The same context passed to BmForEachVariable.
**/
VOID
BmCollectKeyOptions (
  CHAR16               *Name,
  EFI_GUID             *Guid,
  VOID                 *Context
  )
{
  UINTN                        Index;
  BM_COLLECT_KEY_OPTIONS_PARAM *Param;
  VOID                         *KeyOption;
  UINT16                       OptionNumber;
  UINTN                        KeyOptionSize;

  Param = (BM_COLLECT_KEY_OPTIONS_PARAM *) Context;

  if (BmIsKeyOptionVariable (Name, Guid, &OptionNumber)) {
    GetEfiGlobalVariable2 (Name, &KeyOption, &KeyOptionSize);
    ASSERT (KeyOption != NULL);
    if (BmIsKeyOptionValid (KeyOption, KeyOptionSize)) {
      Param->KeyOptions = ReallocatePool (
                            Param->KeyOptionCount * sizeof (EFI_BOOT_MANAGER_KEY_OPTION),
                            (Param->KeyOptionCount + 1) * sizeof (EFI_BOOT_MANAGER_KEY_OPTION),
                            Param->KeyOptions
                            );
      ASSERT (Param->KeyOptions != NULL);
      //
      // Insert the key option in order
      //
      for (Index = 0; Index < Param->KeyOptionCount; Index++) {
        if (OptionNumber < Param->KeyOptions[Index].OptionNumber) {
          break;
        }
      }
      CopyMem (&Param->KeyOptions[Index + 1], &Param->KeyOptions[Index], (Param->KeyOptionCount - Index) * sizeof (EFI_BOOT_MANAGER_KEY_OPTION));
      CopyMem (&Param->KeyOptions[Index], KeyOption, KeyOptionSize);
      Param->KeyOptions[Index].OptionNumber = OptionNumber;
      Param->KeyOptionCount++;
    }
    FreePool (KeyOption);
  }
}

/**
  Return the array of key options.

  @param Count  Return the number of key options.

  @retval NULL  No key option.
  @retval Other Pointer to the key options.
**/
EFI_BOOT_MANAGER_KEY_OPTION *
BmGetKeyOptions (
  OUT UINTN     *Count
  )
{
  BM_COLLECT_KEY_OPTIONS_PARAM Param;

  if (Count == NULL) {
    return NULL;
  }

  Param.KeyOptions = NULL;
  Param.KeyOptionCount = 0;

  BmForEachVariable (BmCollectKeyOptions, (VOID *) &Param);

  *Count = Param.KeyOptionCount;

  return Param.KeyOptions;
}

/**
  Check whether the bit is set in the value.

  @param   Value            The value need to be check.
  @param   Bit              The bit filed need to be check.

  @retval  TRUE             The bit is set.
  @retval  FALSE            The bit is not set.
**/
BOOLEAN
BmBitSet (
  IN UINT32   Value,
  IN UINT32   Bit
  )
{
  return (BOOLEAN) ((Value & Bit) != 0);
}

/**
  Initialize the KeyData and Key[] in the EFI_BOOT_MANAGER_KEY_OPTION.

  @param  Modifier   Input key info.
  @param  Args       Va_list info.
  @param  KeyOption  Key info which need to update.

  @retval  EFI_SUCCESS             Succeed to initialize the KeyData and Key[].
  @return  EFI_INVALID_PARAMETER   Input parameter error.
**/
EFI_STATUS
BmInitializeKeyFields (
  IN UINT32                       Modifier,
  IN VA_LIST                      Args,
  OUT EFI_BOOT_MANAGER_KEY_OPTION *KeyOption
  )
{
  EFI_INPUT_KEY                   *Key;

  if (KeyOption == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Key = NULL;
  while (KeyOption->KeyData.Options.InputKeyCount < sizeof (KeyOption->Keys) / sizeof (KeyOption->Keys[0])) {
    Key = VA_ARG (Args, EFI_INPUT_KEY *);
    if (Key == NULL) {
      break;
    }
    CopyMem (
      &KeyOption->Keys[KeyOption->KeyData.Options.InputKeyCount],
      Key,
      sizeof (EFI_INPUT_KEY)
      );
    KeyOption->KeyData.Options.InputKeyCount++;
  }

  if (Key != NULL) {
    //
    // Too many keys
    //
    return EFI_INVALID_PARAMETER;
  }

  if ((Modifier & ~(EFI_BOOT_MANAGER_SHIFT_PRESSED
                 | EFI_BOOT_MANAGER_CONTROL_PRESSED
                 | EFI_BOOT_MANAGER_ALT_PRESSED
                 | EFI_BOOT_MANAGER_LOGO_PRESSED
                 | EFI_BOOT_MANAGER_MENU_KEY_PRESSED
                 | EFI_BOOT_MANAGER_SYS_REQ_PRESSED
                 )) != 0) {
    return EFI_INVALID_PARAMETER;
  }

  if (BmBitSet (Modifier, EFI_BOOT_MANAGER_SHIFT_PRESSED)) {
    KeyOption->KeyData.Options.ShiftPressed = 1;
  }
  if (BmBitSet (Modifier, EFI_BOOT_MANAGER_CONTROL_PRESSED)) {
    KeyOption->KeyData.Options.ControlPressed = 1;
  }
  if (BmBitSet (Modifier, EFI_BOOT_MANAGER_ALT_PRESSED)) {
    KeyOption->KeyData.Options.AltPressed = 1;
  }
  if (BmBitSet (Modifier, EFI_BOOT_MANAGER_LOGO_PRESSED)) {
    KeyOption->KeyData.Options.LogoPressed = 1;
  }
  if (BmBitSet (Modifier, EFI_BOOT_MANAGER_MENU_KEY_PRESSED)) {
    KeyOption->KeyData.Options.MenuPressed = 1;
  }
  if (BmBitSet (Modifier, EFI_BOOT_MANAGER_SYS_REQ_PRESSED)) {
    KeyOption->KeyData.Options.SysReqPressed = 1;
  }

  return EFI_SUCCESS;
}

/**
  Try to boot the boot option triggered by hot key.
**/
VOID
EFIAPI
EfiBootManagerHotkeyBoot (
  VOID
  )
{
  if (mBmHotkeyBootOption.OptionNumber != LoadOptionNumberUnassigned) {
    EfiBootManagerBoot (&mBmHotkeyBootOption);
    EfiBootManagerFreeLoadOption (&mBmHotkeyBootOption);
    mBmHotkeyBootOption.OptionNumber = LoadOptionNumberUnassigned;
  }
}

/**
  This is the common notification function for HotKeys, it will be registered
  with SimpleTextInEx protocol interface - RegisterKeyNotify() of ConIn handle.

  @param KeyData         A pointer to a buffer that is filled in with the keystroke
                         information for the key that was pressed.

  @retval  EFI_SUCCESS   KeyData is successfully processed.
  @return  EFI_NOT_FOUND Fail to find boot option variable.
**/
EFI_STATUS
EFIAPI
BmHotkeyCallback (
  IN EFI_KEY_DATA     *KeyData
)
{
  LIST_ENTRY                    *Link;
  BM_HOTKEY                     *Hotkey;
  CHAR16                        OptionName[BM_OPTION_NAME_LEN];
  EFI_STATUS                    Status;
  EFI_KEY_DATA                  *HotkeyData;

  if (mBmHotkeyBootOption.OptionNumber != LoadOptionNumberUnassigned) {
    //
    // Do not process sequential hotkey stroke until the current boot option returns
    //
    return EFI_SUCCESS;
  }

  DEBUG ((EFI_D_INFO, "[Bds]BmHotkeyCallback: %04x:%04x\n", KeyData->Key.ScanCode, KeyData->Key.UnicodeChar));

  EfiAcquireLock (&mBmHotkeyLock);
  for ( Link = GetFirstNode (&mBmHotkeyList)
      ; !IsNull (&mBmHotkeyList, Link)
      ; Link = GetNextNode (&mBmHotkeyList, Link)
      ) {
    Hotkey = BM_HOTKEY_FROM_LINK (Link);

    //
    // Is this Key Stroke we are waiting for?
    //
    ASSERT (Hotkey->WaitingKey < (sizeof (Hotkey->KeyData) / sizeof (Hotkey->KeyData[0])));
    HotkeyData = &Hotkey->KeyData[Hotkey->WaitingKey];
    if ((KeyData->Key.ScanCode == HotkeyData->Key.ScanCode) &&
        (KeyData->Key.UnicodeChar == HotkeyData->Key.UnicodeChar) &&
        (((KeyData->KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) ? 
          (KeyData->KeyState.KeyShiftState == HotkeyData->KeyState.KeyShiftState) : TRUE
        )
       ) {

      //
      // Receive an expecting key stroke, transit to next waiting state
      //
      Hotkey->WaitingKey++;

      if (Hotkey->WaitingKey == Hotkey->CodeCount) {
        //
        // Reset to initial waiting state
        //
        Hotkey->WaitingKey = 0;
        //
        // Received the whole key stroke sequence
        //
        Status = gBS->SignalEvent (mBmHotkeyTriggered);
        ASSERT_EFI_ERROR (Status);

        if (!Hotkey->IsContinue) {
          //
          // Launch its BootOption
          //
          UnicodeSPrint (
            OptionName, sizeof (OptionName), L"%s%04x",
            mBmLoadOptionName[LoadOptionTypeBoot], Hotkey->BootOption
            );
          Status = EfiBootManagerVariableToLoadOption (OptionName, &mBmHotkeyBootOption);
          DEBUG ((EFI_D_INFO, "[Bds]Hotkey for %s pressed - %r\n", OptionName, Status));
          if (EFI_ERROR (Status)) {
            mBmHotkeyBootOption.OptionNumber = LoadOptionNumberUnassigned;
          }
        } else {
          DEBUG ((EFI_D_INFO, "[Bds]Continue key pressed!\n"));
        }
      }
    } else {
      //
      // Receive an unexpected key stroke, reset to initial waiting state
      //
      Hotkey->WaitingKey = 0;
    }

  }
  EfiReleaseLock (&mBmHotkeyLock);

  return EFI_SUCCESS;
}

/**
  Return the active Simple Text Input Ex handle array.
  If the SystemTable.ConsoleInHandle is NULL, the function returns all
  founded Simple Text Input Ex handles.
  Otherwise, it just returns the ConsoleInHandle.

  @param Count  Return the handle count.

  @retval The active console handles.
**/
EFI_HANDLE *
BmGetActiveConsoleIn (
  OUT UINTN                             *Count
  )
{
  EFI_STATUS                            Status;
  EFI_HANDLE                            *Handles;

  Handles = NULL;
  *Count  = 0;

  if (gST->ConsoleInHandle != NULL) {
    Status = gBS->OpenProtocol (
                    gST->ConsoleInHandle,
                    &gEfiSimpleTextInputExProtocolGuid,
                    NULL,
                    gImageHandle,
                    NULL,
                    EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                    );
    if (!EFI_ERROR (Status)) {
      Handles = AllocateCopyPool (sizeof (EFI_HANDLE), &gST->ConsoleInHandle);
      if (Handles != NULL) {
        *Count = 1;
      }
    }
  } else {
    Status = gBS->LocateHandleBuffer (
                    ByProtocol,
                    &gEfiSimpleTextInputExProtocolGuid,
                    NULL,
                    Count,
                    &Handles
                    );
  }

  return Handles;
}

/**
  Unregister hotkey notify list.

  @param    Hotkey                Hotkey list.

  @retval   EFI_SUCCESS           Unregister hotkey notify success.
  @retval   Others                Unregister hotkey notify failed.
**/
EFI_STATUS
BmUnregisterHotkeyNotify (
  IN BM_HOTKEY                          *Hotkey
  )
{
  EFI_STATUS                            Status;
  UINTN                                 Index;
  UINTN                                 KeyIndex;
  EFI_HANDLE                            *Handles;
  UINTN                                 HandleCount;
  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL     *TxtInEx;
  VOID                                  *NotifyHandle;

  Handles = BmGetActiveConsoleIn (&HandleCount);
  for (Index = 0; Index < HandleCount; Index++) {
    Status = gBS->HandleProtocol (Handles[Index], &gEfiSimpleTextInputExProtocolGuid, (VOID **) &TxtInEx);
    ASSERT_EFI_ERROR (Status);
    for (KeyIndex = 0; KeyIndex < Hotkey->CodeCount; KeyIndex++) {
      Status = TxtInEx->RegisterKeyNotify (
                          TxtInEx,
                          &Hotkey->KeyData[KeyIndex],
                          BmHotkeyCallback,
                          &NotifyHandle
                          );
      if (!EFI_ERROR (Status)) {
        Status = TxtInEx->UnregisterKeyNotify (TxtInEx, NotifyHandle);
        DEBUG ((EFI_D_INFO, "[Bds]UnregisterKeyNotify: %04x/%04x %r\n", Hotkey->KeyData[KeyIndex].Key.ScanCode, Hotkey->KeyData[KeyIndex].Key.UnicodeChar, Status));
      }
    }
  }

  if (Handles != NULL) {
    FreePool (Handles);
  }

  return EFI_SUCCESS;
}

/**
  Register hotkey notify list.

  @param    TxtInEx               Pointer to EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL protocol.
  @param    Hotkey                Hotkey list.

  @retval   EFI_SUCCESS           Register hotkey notify success.
  @retval   Others                Register hotkey notify failed.
**/
EFI_STATUS
BmRegisterHotkeyNotify (
  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *TxtInEx,
  IN BM_HOTKEY                          *Hotkey
  )
{
  EFI_STATUS                            Status;
  UINTN                                 Index;
  VOID                                  *NotifyHandle;

  for (Index = 0; Index < Hotkey->CodeCount; Index++) {
    Status = TxtInEx->RegisterKeyNotify (
                        TxtInEx,
                        &Hotkey->KeyData[Index],
                        BmHotkeyCallback,
                        &NotifyHandle
                        );
    DEBUG ((
      EFI_D_INFO,
      "[Bds]RegisterKeyNotify: %04x/%04x %08x/%02x %r\n",
      Hotkey->KeyData[Index].Key.ScanCode,
      Hotkey->KeyData[Index].Key.UnicodeChar,
      Hotkey->KeyData[Index].KeyState.KeyShiftState,
      Hotkey->KeyData[Index].KeyState.KeyToggleState,
      Status
      ));
    if (EFI_ERROR (Status)) {
      //
      // some of the hotkey registry failed
      // do not unregister all in case we have both CTRL-ALT-P and CTRL-ALT-P-R
      //
      break;
    }
  }

  return EFI_SUCCESS;
}

/**
  Generate key shift state base on the input key option info.

  @param    Depth                 Which key is checked.
  @param    KeyOption             Input key option info.
  @param    KeyShiftState         Input key shift state.
  @param    KeyShiftStates        Return possible key shift state array.
  @param    KeyShiftStateCount    Possible key shift state count.
**/
VOID
BmGenerateKeyShiftState (
  IN UINTN                             Depth,
  IN EFI_BOOT_MANAGER_KEY_OPTION       *KeyOption,
  IN UINT32                            KeyShiftState,
  IN UINT32                            *KeyShiftStates,
  IN UINTN                             *KeyShiftStateCount
  )
{
  switch (Depth) {
  case 0:
    if (KeyOption->KeyData.Options.ShiftPressed) {
      BmGenerateKeyShiftState (Depth + 1, KeyOption, KeyShiftState | EFI_RIGHT_SHIFT_PRESSED, KeyShiftStates, KeyShiftStateCount);
      BmGenerateKeyShiftState (Depth + 1, KeyOption, KeyShiftState | EFI_LEFT_SHIFT_PRESSED,  KeyShiftStates, KeyShiftStateCount);
    } else {
      BmGenerateKeyShiftState (Depth + 1, KeyOption, KeyShiftState, KeyShiftStates, KeyShiftStateCount);
    }
    break;

  case 1:
    if (KeyOption->KeyData.Options.ControlPressed) {
      BmGenerateKeyShiftState (Depth + 1, KeyOption, KeyShiftState | EFI_RIGHT_CONTROL_PRESSED, KeyShiftStates, KeyShiftStateCount);
      BmGenerateKeyShiftState (Depth + 1, KeyOption, KeyShiftState | EFI_LEFT_CONTROL_PRESSED,  KeyShiftStates, KeyShiftStateCount);
    } else {
      BmGenerateKeyShiftState (Depth + 1, KeyOption, KeyShiftState, KeyShiftStates, KeyShiftStateCount);
    }
    break;

  case 2:
    if (KeyOption->KeyData.Options.AltPressed) {
      BmGenerateKeyShiftState (Depth + 1, KeyOption, KeyShiftState | EFI_RIGHT_ALT_PRESSED, KeyShiftStates, KeyShiftStateCount);
      BmGenerateKeyShiftState (Depth + 1, KeyOption, KeyShiftState | EFI_LEFT_ALT_PRESSED,  KeyShiftStates, KeyShiftStateCount);
    } else {
      BmGenerateKeyShiftState (Depth + 1, KeyOption, KeyShiftState, KeyShiftStates, KeyShiftStateCount);
    }
    break;
  case  3:
    if (KeyOption->KeyData.Options.LogoPressed) {
      BmGenerateKeyShiftState (Depth + 1, KeyOption, KeyShiftState | EFI_RIGHT_LOGO_PRESSED, KeyShiftStates, KeyShiftStateCount);
      BmGenerateKeyShiftState (Depth + 1, KeyOption, KeyShiftState | EFI_LEFT_LOGO_PRESSED,  KeyShiftStates, KeyShiftStateCount);
    } else {
      BmGenerateKeyShiftState (Depth + 1, KeyOption, KeyShiftState, KeyShiftStates, KeyShiftStateCount);
    }
    break;
  case 4:
    if (KeyOption->KeyData.Options.MenuPressed) {
      KeyShiftState |= EFI_MENU_KEY_PRESSED;
    }
    if (KeyOption->KeyData.Options.SysReqPressed) {
      KeyShiftState |= EFI_SYS_REQ_PRESSED;
    }
    KeyShiftStates[*KeyShiftStateCount] = KeyShiftState;
    (*KeyShiftStateCount)++;
    break;
  }
}

/**
  Add it to hot key database, register it to existing TxtInEx.
  New TxtInEx will be automatically registered with all the hot key in dababase

  @param    KeyOption  Input key option info.
**/
EFI_STATUS
BmProcessKeyOption (
  IN EFI_BOOT_MANAGER_KEY_OPTION       *KeyOption
  )
{
  EFI_STATUS                           Status;
  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL    *TxtInEx;
  EFI_HANDLE                           *Handles;
  UINTN                                HandleCount;
  UINTN                                HandleIndex;
  UINTN                                Index;
  BM_HOTKEY                            *Hotkey;
  UINTN                                KeyIndex;
  //
  // 16 is enough to enumerate all the possible combination of LEFT_XXX and RIGHT_XXX
  //
  UINT32                               KeyShiftStates[16];
  UINTN                                KeyShiftStateCount;

  if (KeyOption->KeyData.Options.InputKeyCount > mBmHotkeySupportCount) {
    return EFI_UNSUPPORTED;
  }

  KeyShiftStateCount = 0;
  BmGenerateKeyShiftState (0, KeyOption, EFI_SHIFT_STATE_VALID, KeyShiftStates, &KeyShiftStateCount);
  ASSERT (KeyShiftStateCount <= ARRAY_SIZE (KeyShiftStates));

  EfiAcquireLock (&mBmHotkeyLock);

  Handles = BmGetActiveConsoleIn (&HandleCount);

  for (Index = 0; Index < KeyShiftStateCount; Index++) {
    Hotkey = AllocateZeroPool (sizeof (BM_HOTKEY));
    ASSERT (Hotkey != NULL);

    Hotkey->Signature  = BM_HOTKEY_SIGNATURE;
    Hotkey->BootOption = KeyOption->BootOption;
    Hotkey->IsContinue = (BOOLEAN) (KeyOption == mBmContinueKeyOption);
    Hotkey->CodeCount  = (UINT8) KeyOption->KeyData.Options.InputKeyCount;

    for (KeyIndex = 0; KeyIndex < Hotkey->CodeCount; KeyIndex++) {
      CopyMem (&Hotkey->KeyData[KeyIndex].Key, &KeyOption->Keys[KeyIndex], sizeof (EFI_INPUT_KEY));
      Hotkey->KeyData[KeyIndex].KeyState.KeyShiftState = KeyShiftStates[Index];
    }
    InsertTailList (&mBmHotkeyList, &Hotkey->Link);

    for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
      Status = gBS->HandleProtocol (Handles[HandleIndex], &gEfiSimpleTextInputExProtocolGuid, (VOID **) &TxtInEx);
      ASSERT_EFI_ERROR (Status);
      BmRegisterHotkeyNotify (TxtInEx, Hotkey);
    }
  }

  if (Handles != NULL) {
    FreePool (Handles);
  }
  EfiReleaseLock (&mBmHotkeyLock);

  return EFI_SUCCESS;
}

/**
  Callback function for SimpleTextInEx protocol install events

  @param Event           the event that is signaled.
  @param Context         not used here.

**/
VOID
EFIAPI
BmTxtInExCallback (
  IN EFI_EVENT    Event,
  IN VOID         *Context
  )
{
  EFI_STATUS                         Status;
  UINTN                              BufferSize;
  EFI_HANDLE                         Handle;
  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *TxtInEx;
  LIST_ENTRY                         *Link;

  while (TRUE) {
    BufferSize = sizeof (EFI_HANDLE);
    Status = gBS->LocateHandle (
                    ByRegisterNotify,
                    NULL,
                    mBmTxtInExRegistration,
                    &BufferSize,
                    &Handle
                    );
    if (EFI_ERROR (Status)) {
      //
      // If no more notification events exist
      //
      return ;
    }

    Status = gBS->HandleProtocol (
                    Handle,
                    &gEfiSimpleTextInputExProtocolGuid,
                    (VOID **) &TxtInEx
                    );
    ASSERT_EFI_ERROR (Status);

    //
    // Register the hot key notification for the existing items in the list
    //
    EfiAcquireLock (&mBmHotkeyLock);
    for (Link = GetFirstNode (&mBmHotkeyList); !IsNull (&mBmHotkeyList, Link); Link = GetNextNode (&mBmHotkeyList, Link)) {
      BmRegisterHotkeyNotify (TxtInEx, BM_HOTKEY_FROM_LINK (Link));
    }
    EfiReleaseLock (&mBmHotkeyLock);
  }
}

/**
  Free the key options returned from BmGetKeyOptions.

  @param KeyOptions     Pointer to the key options.
  @param KeyOptionCount Number of the key options.

  @retval EFI_SUCCESS   The key options are freed.
  @retval EFI_NOT_FOUND KeyOptions is NULL.
**/
EFI_STATUS
BmFreeKeyOptions (
  IN EFI_BOOT_MANAGER_KEY_OPTION    *KeyOptions,
  IN UINTN                          KeyOptionCount
  )
{
  if (KeyOptions != NULL) {
    FreePool (KeyOptions);
    return EFI_SUCCESS;
  } else {
    return EFI_NOT_FOUND;
  }
}

/**
  Register the key option to exit the waiting of the Boot Manager timeout.
  Platform should ensure that the continue key option isn't conflict with
  other boot key options.

  @param Modifier     Key shift state.
  @param  ...         Parameter list of pointer of EFI_INPUT_KEY.

  @retval EFI_SUCCESS         Successfully register the continue key option.
  @retval EFI_ALREADY_STARTED The continue key option is already registered.
**/
EFI_STATUS
EFIAPI
EfiBootManagerRegisterContinueKeyOption (
  IN UINT32           Modifier,
  ...
  )
{
  EFI_STATUS                   Status;
  EFI_BOOT_MANAGER_KEY_OPTION  KeyOption;
  VA_LIST                      Args;
  
  if (mBmContinueKeyOption != NULL) {
    return EFI_ALREADY_STARTED;
  }

  ZeroMem (&KeyOption, sizeof (EFI_BOOT_MANAGER_KEY_OPTION));
  VA_START (Args, Modifier);
  Status = BmInitializeKeyFields (Modifier, Args, &KeyOption);
  VA_END (Args);

  if (!EFI_ERROR (Status)) {
    mBmContinueKeyOption = AllocateCopyPool (sizeof (EFI_BOOT_MANAGER_KEY_OPTION), &KeyOption);
    ASSERT (mBmContinueKeyOption != NULL);
    if (mBmHotkeyServiceStarted) {
      BmProcessKeyOption (mBmContinueKeyOption);
    }
  }

  return Status;
}

/**
  Stop the hotkey processing.
  
  @param    Event          Event pointer related to hotkey service.
  @param    Context        Context pass to this function.
**/
VOID
EFIAPI
BmStopHotkeyService (
  IN EFI_EVENT    Event,
  IN VOID         *Context
  )
{
  LIST_ENTRY            *Link;
  BM_HOTKEY             *Hotkey;

  DEBUG ((EFI_D_INFO, "[Bds]Stop Hotkey Service!\n"));
  gBS->CloseEvent (Event);

  EfiAcquireLock (&mBmHotkeyLock);
  for (Link = GetFirstNode (&mBmHotkeyList); !IsNull (&mBmHotkeyList, Link); ) {
    Hotkey = BM_HOTKEY_FROM_LINK (Link);
    BmUnregisterHotkeyNotify (Hotkey);
    Link   = RemoveEntryList (Link);
    FreePool (Hotkey);
  }
  EfiReleaseLock (&mBmHotkeyLock);
}

/**
  Start the hot key service so that the key press can trigger the boot option.

  @param HotkeyTriggered  Return the waitable event and it will be signaled 
                          when a valid hot key is pressed.

  @retval EFI_SUCCESS     The hot key service is started.
**/
EFI_STATUS
EFIAPI
EfiBootManagerStartHotkeyService (
  IN EFI_EVENT                 *HotkeyTriggered
  )
{
  EFI_STATUS                   Status;
  EFI_BOOT_MANAGER_KEY_OPTION  *KeyOptions;
  UINTN                        KeyOptionCount;
  UINTN                        Index;
  EFI_EVENT                    Event;
  UINT32                       *BootOptionSupport;

  GetEfiGlobalVariable2 (EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME, (VOID **) &BootOptionSupport, NULL);
  if (BootOptionSupport != NULL) {
    if ((*BootOptionSupport & EFI_BOOT_OPTION_SUPPORT_KEY)  != 0) {
      mBmHotkeySupportCount = ((*BootOptionSupport & EFI_BOOT_OPTION_SUPPORT_COUNT) >> LowBitSet32 (EFI_BOOT_OPTION_SUPPORT_COUNT));
    }
    FreePool (BootOptionSupport);
  }

  if (mBmHotkeySupportCount == 0) {
    DEBUG ((EFI_D_INFO, "Bds: BootOptionSupport NV variable forbids starting the hotkey service.\n"));
    return EFI_UNSUPPORTED;
  }

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_WAIT,
                  TPL_CALLBACK,
                  EfiEventEmptyFunction,
                  NULL,
                  &mBmHotkeyTriggered
                  );
  ASSERT_EFI_ERROR (Status);

  if (HotkeyTriggered != NULL) {
    *HotkeyTriggered = mBmHotkeyTriggered;
  }

  KeyOptions = BmGetKeyOptions (&KeyOptionCount);
  for (Index = 0; Index < KeyOptionCount; Index ++) {
    BmProcessKeyOption (&KeyOptions[Index]);
  }
  BmFreeKeyOptions (KeyOptions, KeyOptionCount);

  if (mBmContinueKeyOption != NULL) {
    BmProcessKeyOption (mBmContinueKeyOption);
  }

  //
  // Hook hotkey on every future SimpleTextInputEx instance when
  // SystemTable.ConsoleInHandle == NULL, which means the console
  // manager (ConSplitter) is absent.
  //
  if (gST->ConsoleInHandle == NULL) {
    EfiCreateProtocolNotifyEvent (
      &gEfiSimpleTextInputExProtocolGuid,
      TPL_CALLBACK,
      BmTxtInExCallback,
      NULL,
      &mBmTxtInExRegistration
      );
  }

  Status = EfiCreateEventReadyToBootEx (
             TPL_CALLBACK,
             BmStopHotkeyService,
             NULL,
             &Event
             );
  ASSERT_EFI_ERROR (Status);

  mBmHotkeyServiceStarted = TRUE;
  return Status;
}

/**
  Add the key option.
  It adds the key option variable and the key option takes affect immediately.

  @param AddedOption      Return the added key option.
  @param BootOptionNumber The boot option number for the key option.
  @param Modifier         Key shift state.
  @param ...              Parameter list of pointer of EFI_INPUT_KEY.

  @retval EFI_SUCCESS         The key option is added.
  @retval EFI_ALREADY_STARTED The hot key is already used by certain key option.
**/
EFI_STATUS
EFIAPI
EfiBootManagerAddKeyOptionVariable (
  OUT EFI_BOOT_MANAGER_KEY_OPTION *AddedOption,   OPTIONAL
  IN UINT16                       BootOptionNumber,
  IN UINT32                       Modifier,
  ...
  )
{
  EFI_STATUS                     Status;
  VA_LIST                        Args;
  VOID                           *BootOption;
  UINTN                          BootOptionSize;
  CHAR16                         BootOptionName[BM_OPTION_NAME_LEN];
  EFI_BOOT_MANAGER_KEY_OPTION    KeyOption;
  EFI_BOOT_MANAGER_KEY_OPTION    *KeyOptions;
  UINTN                          KeyOptionCount;
  UINTN                          Index;
  UINTN                          KeyOptionNumber;
  CHAR16                         KeyOptionName[sizeof ("Key####")];

  UnicodeSPrint (
    BootOptionName, sizeof (BootOptionName), L"%s%04x",
    mBmLoadOptionName[LoadOptionTypeBoot], BootOptionNumber
    );
  GetEfiGlobalVariable2 (BootOptionName, &BootOption, &BootOptionSize);

  if (BootOption == NULL) {
    return EFI_NOT_FOUND;
  }

  ZeroMem (&KeyOption, sizeof (EFI_BOOT_MANAGER_KEY_OPTION));
  KeyOption.BootOption = BootOptionNumber;
  Status = gBS->CalculateCrc32 (BootOption, BootOptionSize, &KeyOption.BootOptionCrc);
  ASSERT_EFI_ERROR (Status);
  FreePool (BootOption);

  VA_START (Args, Modifier);
  Status = BmInitializeKeyFields (Modifier, Args, &KeyOption);
  VA_END (Args);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  KeyOptionNumber = LoadOptionNumberUnassigned;
  //
  // Check if the hot key sequence was defined already
  //
  KeyOptions = BmGetKeyOptions (&KeyOptionCount);
  for (Index = 0; Index < KeyOptionCount; Index++) {
    if ((KeyOptions[Index].KeyData.PackedValue == KeyOption.KeyData.PackedValue) &&
      (CompareMem (KeyOptions[Index].Keys, KeyOption.Keys, KeyOption.KeyData.Options.InputKeyCount * sizeof (EFI_INPUT_KEY)) == 0)) {
      break;
    }

    if ((KeyOptionNumber == LoadOptionNumberUnassigned) &&
        (KeyOptions[Index].OptionNumber > Index)
       ){
      KeyOptionNumber = Index;
    }
  }
  BmFreeKeyOptions (KeyOptions, KeyOptionCount);

  if (Index < KeyOptionCount) {
    return EFI_ALREADY_STARTED;
  }

  if (KeyOptionNumber == LoadOptionNumberUnassigned) {
    KeyOptionNumber = KeyOptionCount;
  }

  UnicodeSPrint (KeyOptionName, sizeof (KeyOptionName), L"Key%04x", KeyOptionNumber);

  Status = gRT->SetVariable (
                  KeyOptionName,
                  &gEfiGlobalVariableGuid,
                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
                  BmSizeOfKeyOption (&KeyOption),
                  &KeyOption
                  );
  if (!EFI_ERROR (Status)) {
    //
    // Return the Key Option in case needed by caller
    //
    if (AddedOption != NULL) {
      CopyMem (AddedOption, &KeyOption, sizeof (EFI_BOOT_MANAGER_KEY_OPTION));
    }

    //
    // Register the newly added hot key
    // Calling this function before EfiBootManagerStartHotkeyService doesn't
    // need to call BmProcessKeyOption
    //
    if (mBmHotkeyServiceStarted) {
      BmProcessKeyOption (&KeyOption);
    }
  }

  return Status;
}

/**
  Delete the Key Option variable and unregister the hot key

  @param DeletedOption  Return the deleted key options.
  @param Modifier       Key shift state.
  @param ...            Parameter list of pointer of EFI_INPUT_KEY.

  @retval EFI_SUCCESS   The key option is deleted.
  @retval EFI_NOT_FOUND The key option cannot be found.
**/
EFI_STATUS
EFIAPI
EfiBootManagerDeleteKeyOptionVariable (
  IN EFI_BOOT_MANAGER_KEY_OPTION *DeletedOption, OPTIONAL
  IN UINT32                      Modifier,
  ...
  )
{
  EFI_STATUS                     Status;
  UINTN                          Index;
  VA_LIST                        Args;
  EFI_BOOT_MANAGER_KEY_OPTION    KeyOption;
  EFI_BOOT_MANAGER_KEY_OPTION    *KeyOptions;
  UINTN                          KeyOptionCount;
  LIST_ENTRY                     *Link;
  BM_HOTKEY                      *Hotkey;
  UINT32                         ShiftState;
  BOOLEAN                        Match;
  CHAR16                         KeyOptionName[sizeof ("Key####")];

  ZeroMem (&KeyOption, sizeof (EFI_BOOT_MANAGER_KEY_OPTION));
  VA_START (Args, Modifier);
  Status = BmInitializeKeyFields (Modifier, Args, &KeyOption);
  VA_END (Args);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  EfiAcquireLock (&mBmHotkeyLock);
  //
  // Delete the key option from active hot key list
  // Could have multiple entries when modifier isn't 0 because we map the ShiftPressed to RIGHT_SHIFT and RIGHT_SHIFT
  //
  for (Link = GetFirstNode (&mBmHotkeyList); !IsNull (&mBmHotkeyList, Link); ) {
    Hotkey = BM_HOTKEY_FROM_LINK (Link);
    Match  = (BOOLEAN) (Hotkey->CodeCount == KeyOption.KeyData.Options.InputKeyCount);

    for (Index = 0; Match && (Index < Hotkey->CodeCount); Index++) {
      ShiftState = Hotkey->KeyData[Index].KeyState.KeyShiftState;
      if (
        (BmBitSet (ShiftState, EFI_RIGHT_SHIFT_PRESSED | EFI_LEFT_SHIFT_PRESSED) != KeyOption.KeyData.Options.ShiftPressed) ||
        (BmBitSet (ShiftState, EFI_RIGHT_CONTROL_PRESSED | EFI_LEFT_CONTROL_PRESSED) != KeyOption.KeyData.Options.ControlPressed) ||
        (BmBitSet (ShiftState, EFI_RIGHT_ALT_PRESSED | EFI_LEFT_ALT_PRESSED) != KeyOption.KeyData.Options.AltPressed) ||
        (BmBitSet (ShiftState, EFI_RIGHT_LOGO_PRESSED | EFI_LEFT_LOGO_PRESSED) != KeyOption.KeyData.Options.LogoPressed) ||
        (BmBitSet (ShiftState, EFI_MENU_KEY_PRESSED) != KeyOption.KeyData.Options.MenuPressed) ||
        (BmBitSet (ShiftState, EFI_SYS_REQ_PRESSED) != KeyOption.KeyData.Options.SysReqPressed) ||
        (CompareMem (&Hotkey->KeyData[Index].Key, &KeyOption.Keys[Index], sizeof (EFI_INPUT_KEY)) != 0)
        ) {
        //
        // Break when any field doesn't match
        //
        Match = FALSE;
        break;
      }
    }

    if (Match) {
      Link = RemoveEntryList (Link);
      FreePool (Hotkey);
    } else {
      Link = GetNextNode (&mBmHotkeyList, Link);
    }
  }

  //
  // Delete the key option from the variable
  //
  Status     = EFI_NOT_FOUND;
  KeyOptions = BmGetKeyOptions (&KeyOptionCount);
  for (Index = 0; Index < KeyOptionCount; Index++) {
    if ((KeyOptions[Index].KeyData.PackedValue == KeyOption.KeyData.PackedValue) &&
        (CompareMem (
           KeyOptions[Index].Keys, KeyOption.Keys,
           KeyOption.KeyData.Options.InputKeyCount * sizeof (EFI_INPUT_KEY)) == 0)
       ) {
      UnicodeSPrint (KeyOptionName, sizeof (KeyOptionName), L"Key%04x", KeyOptions[Index].OptionNumber);
      Status = gRT->SetVariable (
                 KeyOptionName,
                 &gEfiGlobalVariableGuid,
                 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
                 0,
                 NULL
                 );
      //
      // Return the deleted key option in case needed by caller
      //
      if (DeletedOption != NULL) {
        CopyMem (DeletedOption, &KeyOptions[Index], sizeof (EFI_BOOT_MANAGER_KEY_OPTION));
      }
      break;
    }
  }
  BmFreeKeyOptions (KeyOptions, KeyOptionCount);

  EfiReleaseLock (&mBmHotkeyLock);

  return Status;
}
