/** @file
  Hotkey library functions.

Copyright (c) 2011 - 2016, 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 (
  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 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;
  EFI_BOOT_MANAGER_KEY_OPTION  *KeyOption;
  UINT16                       OptionNumber;
  UINTN                        KeyOptionSize;

  Param = (BM_COLLECT_KEY_OPTIONS_PARAM *) Context;

  if (BmIsKeyOptionVariable (Name, Guid, &OptionNumber)) {
    GetEfiGlobalVariable2 (Name, (VOID**) &KeyOption, &KeyOptionSize);
    ASSERT (KeyOption != NULL);
    KeyOption->OptionNumber = OptionNumber;
    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 (KeyOption->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, BmSizeOfKeyOption (KeyOption));
      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;
}

/**
  Callback function for event.
  
  @param    Event          Event for this callback function.
  @param    Context        Context pass to this function.
**/
VOID
EFIAPI
BmEmptyFunction (
  IN EFI_EVENT                Event,
  IN VOID                     *Context
  )
{
}

/**
  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 <= sizeof (KeyShiftStates) / sizeof (KeyShiftStates[0]));

  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;

  Status = GetEfiGlobalVariable2 (EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME, (VOID **) &BootOptionSupport, NULL);
  ASSERT (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,
                  BmEmptyFunction,
                  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;
}
