X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=IntelFrameworkModulePkg%2FUniversal%2FBdsDxe%2FHotkey.c;h=d0d9bb077bfb2b6e14d999abb35ca86a7576388a;hp=bfad7ce7552b6ea94fe9a559c692ab8da1c86664;hb=d394581d11ff0c7ba2c32e01a676c80e090ecdb8;hpb=5c08e1173703234cc2913757f237ee916087498a diff --git a/IntelFrameworkModulePkg/Universal/BdsDxe/Hotkey.c b/IntelFrameworkModulePkg/Universal/BdsDxe/Hotkey.c index bfad7ce755..d0d9bb077b 100644 --- a/IntelFrameworkModulePkg/Universal/BdsDxe/Hotkey.c +++ b/IntelFrameworkModulePkg/Universal/BdsDxe/Hotkey.c @@ -2,8 +2,8 @@ Provides a way for 3rd party applications to register themselves for launch by the Boot Manager based on hot key -Copyright (c) 2007 - 2008, Intel Corporation.
-All rights reserved. This program and the accompanying materials +Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.
+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 @@ -16,10 +16,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "Hotkey.h" -LIST_ENTRY mHotkeyList = INITIALIZE_LIST_HEAD_VARIABLE (mHotkeyList); -BOOLEAN mHotkeyCallbackPending = FALSE; -EFI_EVENT mHotkeyEvent; -VOID *mHotkeyRegistration; +LIST_ENTRY mHotkeyList = INITIALIZE_LIST_HEAD_VARIABLE (mHotkeyList); +BDS_COMMON_OPTION *mHotkeyBootOption = NULL; +EFI_EVENT mHotkeyEvent; +VOID *mHotkeyRegistration; /** @@ -101,11 +101,11 @@ RegisterHotkey ( return EFI_INVALID_PARAMETER; } - KeyOptionSize = sizeof (EFI_KEY_OPTION) + GET_KEY_CODE_COUNT (KeyOption->KeyData.PackedValue) * sizeof (EFI_INPUT_KEY); + KeyOptionSize = sizeof (EFI_KEY_OPTION) + KeyOption->KeyData.Options.InputKeyCount * sizeof (EFI_INPUT_KEY); UpdateBootOption = FALSE; // - // check whether HotKey conflict with keys used by Setup Browser + // Check whether HotKey conflict with keys used by Setup Browser // KeyOrder = BdsLibGetVariableAndSize ( VAR_KEY_ORDER, @@ -132,6 +132,7 @@ RegisterHotkey ( &gEfiGlobalVariableGuid, &TempOptionSize ); + ASSERT (TempOption != NULL); if (CompareMem (TempOption, KeyOption, TempOptionSize) == 0) { // @@ -143,7 +144,7 @@ RegisterHotkey ( } if (KeyOption->KeyData.PackedValue == TempOption->KeyData.PackedValue) { - if (GET_KEY_CODE_COUNT (KeyOption->KeyData.PackedValue) == 0 || + if (KeyOption->KeyData.Options.InputKeyCount == 0 || CompareMem ( ((UINT8 *) TempOption) + sizeof (EFI_KEY_OPTION), ((UINT8 *) KeyOption) + sizeof (EFI_KEY_OPTION), @@ -299,6 +300,50 @@ UnregisterHotkey ( return Status; } +/** + Try to boot the boot option triggered by hotkey. +**/ +VOID +HotkeyBoot ( + VOID + ) +{ + EFI_STATUS Status; + UINTN ExitDataSize; + CHAR16 *ExitData; + + if (mHotkeyBootOption != NULL) { + BdsLibConnectDevicePath (mHotkeyBootOption->DevicePath); + + // + // Clear the screen before launch this BootOption + // + gST->ConOut->Reset (gST->ConOut, FALSE); + + Status = BdsLibBootViaBootOption (mHotkeyBootOption, mHotkeyBootOption->DevicePath, &ExitDataSize, &ExitData); + + if (EFI_ERROR (Status)) { + // + // Call platform action to indicate the boot fail + // + mHotkeyBootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_FAILED)); + PlatformBdsBootFail (mHotkeyBootOption, Status, ExitData, ExitDataSize); + } else { + // + // Call platform action to indicate the boot success + // + mHotkeyBootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED)); + PlatformBdsBootSuccess (mHotkeyBootOption); + } + FreePool (mHotkeyBootOption->Description); + FreePool (mHotkeyBootOption->DevicePath); + FreePool (mHotkeyBootOption->LoadOptions); + FreePool (mHotkeyBootOption); + + mHotkeyBootOption = NULL; + } +} + /** This is the common notification function for HotKeys, it will be registered @@ -311,6 +356,7 @@ UnregisterHotkey ( @return EFI_NOT_FOUND Fail to find boot option variable. **/ EFI_STATUS +EFIAPI HotkeyCallback ( IN EFI_KEY_DATA *KeyData ) @@ -320,24 +366,22 @@ HotkeyCallback ( LIST_ENTRY *Link; BDS_HOTKEY_OPTION *Hotkey; UINT16 Buffer[10]; - BDS_COMMON_OPTION *BootOption; - UINTN ExitDataSize; - CHAR16 *ExitData; EFI_STATUS Status; EFI_KEY_DATA *HotkeyData; - if (mHotkeyCallbackPending) { + if (mHotkeyBootOption != NULL) { // - // When responsing to a Hotkey, ignore sequential hotkey stroke until - // the current Boot#### load option returned + // Do not process sequential hotkey stroke until the current boot option returns // return EFI_SUCCESS; } - Status = EFI_SUCCESS; - Link = GetFirstNode (&mHotkeyList); + Status = EFI_SUCCESS; - while (!IsNull (&mHotkeyList, Link)) { + for ( Link = GetFirstNode (&mHotkeyList) + ; !IsNull (&mHotkeyList, Link) + ; Link = GetNextNode (&mHotkeyList, Link) + ) { HotkeyCatched = FALSE; Hotkey = BDS_HOTKEY_OPTION_FROM_LINK (Link); @@ -347,26 +391,19 @@ HotkeyCallback ( 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) && - ((HotkeyData->KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) ? (KeyData->KeyState.KeyShiftState == HotkeyData->KeyState.KeyShiftState) : 1)) { + (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 + // For hotkey of key combination, transit to next waiting state // - if (Hotkey->CodeCount > 1) { - // - // For hotkey of key combination, transit to next waiting state - // - Hotkey->WaitingKey++; + Hotkey->WaitingKey++; - if (Hotkey->WaitingKey == Hotkey->CodeCount) { - // - // Received the whole key stroke sequence - // - HotkeyCatched = TRUE; - } - } else { + if (Hotkey->WaitingKey == Hotkey->CodeCount) { // - // For hotkey of single key stroke + // Received the whole key stroke sequence // HotkeyCatched = TRUE; } @@ -389,38 +426,8 @@ HotkeyCallback ( InitializeListHead (&BootLists); UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", Hotkey->BootOptionNumber); - BootOption = BdsLibVariableToOption (&BootLists, Buffer); - if (BootOption == NULL) { - return EFI_NOT_FOUND; - } - BootOption->BootCurrent = Hotkey->BootOptionNumber; - BdsLibConnectDevicePath (BootOption->DevicePath); - - // - // Clear the screen before launch this BootOption - // - gST->ConOut->Reset (gST->ConOut, FALSE); - - mHotkeyCallbackPending = TRUE; - Status = BdsLibBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData); - mHotkeyCallbackPending = FALSE; - - if (EFI_ERROR (Status)) { - // - // Call platform action to indicate the boot fail - // - BootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_FAILED)); - PlatformBdsBootFail (BootOption, Status, ExitData, ExitDataSize); - } else { - // - // Call platform action to indicate the boot success - // - BootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED)); - PlatformBdsBootSuccess (BootOption); - } + mHotkeyBootOption = BdsLibVariableToOption (&BootLists, Buffer); } - - Link = GetNextNode (&mHotkeyList, Link); } return Status; @@ -468,7 +475,7 @@ HotkeyRegisterNotify ( return Status; } Index ++; - } while (Index < Hotkey->CodeCount); + } while ((Index < Hotkey->CodeCount) && (Index < (sizeof (Hotkey->KeyData) / sizeof (EFI_KEY_DATA)))); Link = GetNextNode (&mHotkeyList, Link); } @@ -538,7 +545,7 @@ HotkeyInsertList ( BDS_HOTKEY_OPTION *HotkeyLeft; BDS_HOTKEY_OPTION *HotkeyRight; UINTN Index; - UINT32 KeyOptions; + EFI_BOOT_KEY_DATA KeyOptions; UINT32 KeyShiftStateLeft; UINT32 KeyShiftStateRight; EFI_INPUT_KEY *InputKey; @@ -552,19 +559,33 @@ HotkeyInsertList ( HotkeyLeft->Signature = BDS_HOTKEY_OPTION_SIGNATURE; HotkeyLeft->BootOptionNumber = KeyOption->BootOption; - KeyOptions = KeyOption->KeyData.PackedValue; + KeyOptions = KeyOption->KeyData; - HotkeyLeft->CodeCount = (UINT8) GET_KEY_CODE_COUNT (KeyOptions); + HotkeyLeft->CodeCount = (UINT8) KeyOptions.Options.InputKeyCount; // // Map key shift state from KeyOptions to EFI_KEY_DATA.KeyState // - KeyShiftStateRight = (KeyOptions & EFI_KEY_OPTION_SHIFT) | - ((KeyOptions & EFI_KEY_OPTION_CONTROL) << 1) | - ((KeyOptions & EFI_KEY_OPTION_ALT) << 2) | - ((KeyOptions & EFI_KEY_OPTION_LOGO) << 3) | - ((KeyOptions & (EFI_KEY_OPTION_MENU | EFI_KEY_OPTION_SYSREQ)) << 4) | - EFI_SHIFT_STATE_VALID; + KeyShiftStateRight = EFI_SHIFT_STATE_VALID; + if (KeyOptions.Options.ShiftPressed) { + KeyShiftStateRight |= EFI_RIGHT_SHIFT_PRESSED; + } + if (KeyOptions.Options.ControlPressed) { + KeyShiftStateRight |= EFI_RIGHT_CONTROL_PRESSED; + } + if (KeyOptions.Options.AltPressed) { + KeyShiftStateRight |= EFI_RIGHT_ALT_PRESSED; + } + if (KeyOptions.Options.LogoPressed) { + KeyShiftStateRight |= EFI_RIGHT_LOGO_PRESSED; + } + if (KeyOptions.Options.MenuPressed) { + KeyShiftStateRight |= EFI_MENU_KEY_PRESSED; + } + if (KeyOptions.Options.SysReqPressed) { + KeyShiftStateRight |= EFI_SYS_REQ_PRESSED; + } + KeyShiftStateLeft = (KeyShiftStateRight & 0xffffff00) | ((KeyShiftStateRight & 0xff) << 1); @@ -636,12 +657,14 @@ InitializeHotkeyService ( // // Export our capability - EFI_BOOT_OPTION_SUPPORT_KEY and EFI_BOOT_OPTION_SUPPORT_APP + // with maximum number of key presses of 3 // BootOptionSupport = EFI_BOOT_OPTION_SUPPORT_KEY | EFI_BOOT_OPTION_SUPPORT_APP; + SET_BOOT_OPTION_SUPPORT_KEY_COUNT (BootOptionSupport, 3); Status = gRT->SetVariable ( L"BootOptionSupport", &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, sizeof (UINT32), &BootOptionSupport );