]> git.proxmox.com Git - mirror_edk2.git/blame - 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
CommitLineData
5c08e117 1/** @file\r
2 Provides a way for 3rd party applications to register themselves for launch by the\r
3 Boot Manager based on hot key\r
4\r
2df686c6 5Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>\r
180a5a35 6This program and the accompanying materials\r
5c08e117 7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "Hotkey.h"\r
17\r
18\r
d394581d
RN
19LIST_ENTRY mHotkeyList = INITIALIZE_LIST_HEAD_VARIABLE (mHotkeyList);\r
20BDS_COMMON_OPTION *mHotkeyBootOption = NULL;\r
21EFI_EVENT mHotkeyEvent;\r
22VOID *mHotkeyRegistration;\r
5c08e117 23\r
24\r
25/**\r
26 Check if the Key Option is valid or not.\r
27\r
28 @param KeyOption The Hot Key Option to be checked.\r
29\r
30 @retval TRUE The Hot Key Option is valid.\r
31 @retval FALSE The Hot Key Option is invalid.\r
32\r
33**/\r
34BOOLEAN\r
35IsKeyOptionValid (\r
36 IN EFI_KEY_OPTION *KeyOption\r
37)\r
38{\r
39 UINT16 BootOptionName[10];\r
40 UINT8 *BootOptionVar;\r
41 UINTN BootOptionSize;\r
42 UINT32 Crc;\r
43\r
44 //\r
45 // Check whether corresponding Boot Option exist\r
46 //\r
47 UnicodeSPrint (BootOptionName, sizeof (BootOptionName), L"Boot%04x", KeyOption->BootOption);\r
48 BootOptionVar = BdsLibGetVariableAndSize (\r
49 BootOptionName,\r
50 &gEfiGlobalVariableGuid,\r
51 &BootOptionSize\r
52 );\r
53\r
54 if (BootOptionVar == NULL || BootOptionSize == 0) {\r
55 return FALSE;\r
56 }\r
57\r
58 //\r
59 // Check CRC for Boot Option\r
60 //\r
61 gBS->CalculateCrc32 (BootOptionVar, BootOptionSize, &Crc);\r
62 FreePool (BootOptionVar);\r
63\r
64 return (BOOLEAN) ((KeyOption->BootOptionCrc == Crc) ? TRUE : FALSE);\r
65}\r
66\r
d394581d
RN
67/**\r
68 Try to boot the boot option triggered by hotkey.\r
2df686c6 69 @retval EFI_SUCCESS There is HotkeyBootOption & it is processed\r
70 @retval EFI_NOT_FOUND There is no HotkeyBootOption\r
d394581d 71**/\r
2df686c6 72EFI_STATUS\r
d394581d
RN
73HotkeyBoot (\r
74 VOID\r
75 )\r
2df686c6 76{ \r
d394581d
RN
77 EFI_STATUS Status;\r
78 UINTN ExitDataSize;\r
79 CHAR16 *ExitData;\r
2df686c6 80\r
81 if (mHotkeyBootOption == NULL) {\r
82 return EFI_NOT_FOUND;\r
83 } \r
d394581d 84 \r
2df686c6 85 BdsLibConnectDevicePath (mHotkeyBootOption->DevicePath);\r
86\r
87 //\r
88 // Clear the screen before launch this BootOption\r
89 //\r
90 gST->ConOut->Reset (gST->ConOut, FALSE);\r
91\r
92 Status = BdsLibBootViaBootOption (mHotkeyBootOption, mHotkeyBootOption->DevicePath, &ExitDataSize, &ExitData);\r
d394581d 93\r
2df686c6 94 if (EFI_ERROR (Status)) {\r
d394581d 95 //\r
2df686c6 96 // Call platform action to indicate the boot fail\r
d394581d 97 //\r
2df686c6 98 mHotkeyBootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_FAILED));\r
99 PlatformBdsBootFail (mHotkeyBootOption, Status, ExitData, ExitDataSize);\r
100 } else {\r
101 //\r
102 // Call platform action to indicate the boot success\r
103 //\r
104 mHotkeyBootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED));\r
105 PlatformBdsBootSuccess (mHotkeyBootOption);\r
106 }\r
107 FreePool (mHotkeyBootOption->Description);\r
108 FreePool (mHotkeyBootOption->DevicePath);\r
109 FreePool (mHotkeyBootOption->LoadOptions);\r
110 FreePool (mHotkeyBootOption);\r
d394581d 111\r
2df686c6 112 mHotkeyBootOption = NULL;\r
d394581d 113\r
2df686c6 114 return EFI_SUCCESS;\r
d394581d
RN
115}\r
116\r
5c08e117 117/**\r
118\r
119 This is the common notification function for HotKeys, it will be registered\r
120 with SimpleTextInEx protocol interface - RegisterKeyNotify() of ConIn handle.\r
121\r
122 @param KeyData A pointer to a buffer that is filled in with the keystroke\r
123 information for the key that was pressed.\r
124\r
125 @retval EFI_SUCCESS KeyData is successfully processed.\r
126 @return EFI_NOT_FOUND Fail to find boot option variable.\r
127**/\r
128EFI_STATUS\r
6ba0bc7c 129EFIAPI\r
5c08e117 130HotkeyCallback (\r
131 IN EFI_KEY_DATA *KeyData\r
132)\r
133{\r
134 BOOLEAN HotkeyCatched;\r
135 LIST_ENTRY BootLists;\r
136 LIST_ENTRY *Link;\r
137 BDS_HOTKEY_OPTION *Hotkey;\r
138 UINT16 Buffer[10];\r
5c08e117 139 EFI_STATUS Status;\r
140 EFI_KEY_DATA *HotkeyData;\r
141\r
d394581d 142 if (mHotkeyBootOption != NULL) {\r
5c08e117 143 //\r
d394581d 144 // Do not process sequential hotkey stroke until the current boot option returns\r
5c08e117 145 //\r
146 return EFI_SUCCESS;\r
147 }\r
148\r
d394581d 149 Status = EFI_SUCCESS;\r
5c08e117 150\r
d394581d
RN
151 for ( Link = GetFirstNode (&mHotkeyList)\r
152 ; !IsNull (&mHotkeyList, Link)\r
153 ; Link = GetNextNode (&mHotkeyList, Link)\r
154 ) {\r
5c08e117 155 HotkeyCatched = FALSE;\r
156 Hotkey = BDS_HOTKEY_OPTION_FROM_LINK (Link);\r
157\r
158 //\r
159 // Is this Key Stroke we are waiting for?\r
160 //\r
161 ASSERT (Hotkey->WaitingKey < (sizeof (Hotkey->KeyData) / sizeof (Hotkey->KeyData[0])));\r
162 HotkeyData = &Hotkey->KeyData[Hotkey->WaitingKey];\r
163 if ((KeyData->Key.ScanCode == HotkeyData->Key.ScanCode) &&\r
d394581d
RN
164 (KeyData->Key.UnicodeChar == HotkeyData->Key.UnicodeChar) &&\r
165 (((KeyData->KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) ? \r
166 (KeyData->KeyState.KeyShiftState == HotkeyData->KeyState.KeyShiftState) : TRUE\r
167 )\r
168 ) {\r
5c08e117 169 //\r
d394581d 170 // For hotkey of key combination, transit to next waiting state\r
5c08e117 171 //\r
d394581d 172 Hotkey->WaitingKey++;\r
5c08e117 173\r
d394581d 174 if (Hotkey->WaitingKey == Hotkey->CodeCount) {\r
5c08e117 175 //\r
d394581d 176 // Received the whole key stroke sequence\r
5c08e117 177 //\r
178 HotkeyCatched = TRUE;\r
179 }\r
180 } else {\r
181 //\r
182 // Receive an unexpected key stroke, reset to initial waiting state\r
183 //\r
184 Hotkey->WaitingKey = 0;\r
185 }\r
186\r
187 if (HotkeyCatched) {\r
188 //\r
189 // Reset to initial waiting state\r
190 //\r
191 Hotkey->WaitingKey = 0;\r
192\r
193 //\r
194 // Launch its BootOption\r
195 //\r
196 InitializeListHead (&BootLists);\r
197\r
198 UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", Hotkey->BootOptionNumber);\r
d394581d 199 mHotkeyBootOption = BdsLibVariableToOption (&BootLists, Buffer);\r
5c08e117 200 }\r
5c08e117 201 }\r
202\r
203 return Status;\r
204}\r
205\r
206/**\r
207 Register the common HotKey notify function to given SimpleTextInEx protocol instance.\r
208\r
209 @param SimpleTextInEx Simple Text Input Ex protocol instance\r
210\r
211 @retval EFI_SUCCESS Register hotkey notification function successfully.\r
212 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures.\r
213\r
214**/\r
215EFI_STATUS\r
216HotkeyRegisterNotify (\r
217 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleTextInEx\r
218)\r
219{\r
220 UINTN Index;\r
221 EFI_STATUS Status;\r
222 LIST_ENTRY *Link;\r
223 BDS_HOTKEY_OPTION *Hotkey;\r
224\r
225 //\r
226 // Register notification function for each hotkey\r
227 //\r
228 Link = GetFirstNode (&mHotkeyList);\r
229\r
230 while (!IsNull (&mHotkeyList, Link)) {\r
231 Hotkey = BDS_HOTKEY_OPTION_FROM_LINK (Link);\r
232\r
233 Index = 0;\r
234 do {\r
235 Status = SimpleTextInEx->RegisterKeyNotify (\r
236 SimpleTextInEx,\r
237 &Hotkey->KeyData[Index],\r
238 HotkeyCallback,\r
239 &Hotkey->NotifyHandle\r
240 );\r
241 if (EFI_ERROR (Status)) {\r
242 //\r
243 // some of the hotkey registry failed\r
244 //\r
245 return Status;\r
246 }\r
247 Index ++;\r
84fa6c17 248 } while ((Index < Hotkey->CodeCount) && (Index < (sizeof (Hotkey->KeyData) / sizeof (EFI_KEY_DATA))));\r
5c08e117 249\r
250 Link = GetNextNode (&mHotkeyList, Link);\r
251 }\r
252\r
253 return EFI_SUCCESS;\r
254}\r
255\r
256/**\r
257 Callback function for SimpleTextInEx protocol install events\r
258\r
259 @param Event the event that is signaled.\r
260 @param Context not used here.\r
261\r
262**/\r
263VOID\r
264EFIAPI\r
265HotkeyEvent (\r
266 IN EFI_EVENT Event,\r
267 IN VOID *Context\r
268 )\r
269{\r
270 EFI_STATUS Status;\r
271 UINTN BufferSize;\r
272 EFI_HANDLE Handle;\r
273 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleTextInEx;\r
274\r
275 while (TRUE) {\r
276 BufferSize = sizeof (EFI_HANDLE);\r
277 Status = gBS->LocateHandle (\r
278 ByRegisterNotify,\r
279 NULL,\r
280 mHotkeyRegistration,\r
281 &BufferSize,\r
282 &Handle\r
283 );\r
284 if (EFI_ERROR (Status)) {\r
285 //\r
286 // If no more notification events exist\r
287 //\r
288 return ;\r
289 }\r
290\r
291 Status = gBS->HandleProtocol (\r
292 Handle,\r
293 &gEfiSimpleTextInputExProtocolGuid,\r
294 (VOID **) &SimpleTextInEx\r
295 );\r
296 ASSERT_EFI_ERROR (Status);\r
297\r
298 HotkeyRegisterNotify (SimpleTextInEx);\r
299 }\r
300}\r
301\r
302/**\r
303 Insert Key Option to hotkey list.\r
304\r
305 @param KeyOption The Hot Key Option to be added to hotkey list.\r
306\r
307 @retval EFI_SUCCESS Add to hotkey list success.\r
308 @retval EFI_OUT_OF_RESOURCES Fail to allocate memory resource.\r
309**/\r
310EFI_STATUS\r
311HotkeyInsertList (\r
312 IN EFI_KEY_OPTION *KeyOption\r
313)\r
314{\r
315 BDS_HOTKEY_OPTION *HotkeyLeft;\r
316 BDS_HOTKEY_OPTION *HotkeyRight;\r
317 UINTN Index;\r
5c08e117 318 UINT32 KeyShiftStateLeft;\r
319 UINT32 KeyShiftStateRight;\r
320 EFI_INPUT_KEY *InputKey;\r
321 EFI_KEY_DATA *KeyData;\r
322\r
323 HotkeyLeft = AllocateZeroPool (sizeof (BDS_HOTKEY_OPTION));\r
324 if (HotkeyLeft == NULL) {\r
325 return EFI_OUT_OF_RESOURCES;\r
326 }\r
327\r
328 HotkeyLeft->Signature = BDS_HOTKEY_OPTION_SIGNATURE;\r
329 HotkeyLeft->BootOptionNumber = KeyOption->BootOption;\r
53cdd439 330 HotkeyLeft->CodeCount = (UINT8) KEY_OPTION_INPUT_KEY_COUNT (KeyOption);\r
5c08e117 331\r
332 //\r
333 // Map key shift state from KeyOptions to EFI_KEY_DATA.KeyState\r
334 //\r
a9e7937a 335 KeyShiftStateRight = EFI_SHIFT_STATE_VALID;\r
53cdd439 336 if (KEY_OPTION_SHIFT_PRESSED (KeyOption)) {\r
a9e7937a 337 KeyShiftStateRight |= EFI_RIGHT_SHIFT_PRESSED;\r
338 }\r
53cdd439 339 if (KEY_OPTION_CONTROL_PRESSED (KeyOption)) {\r
a9e7937a 340 KeyShiftStateRight |= EFI_RIGHT_CONTROL_PRESSED;\r
341 }\r
53cdd439 342 if (KEY_OPTION_ALT_PRESSED (KeyOption)) {\r
a9e7937a 343 KeyShiftStateRight |= EFI_RIGHT_ALT_PRESSED;\r
344 }\r
53cdd439 345 if (KEY_OPTION_LOGO_PRESSED (KeyOption)) {\r
a9e7937a 346 KeyShiftStateRight |= EFI_RIGHT_LOGO_PRESSED;\r
347 }\r
53cdd439 348 if (KEY_OPTION_MENU_PRESSED (KeyOption)) {\r
a9e7937a 349 KeyShiftStateRight |= EFI_MENU_KEY_PRESSED;\r
350 }\r
53cdd439 351 if (KEY_OPTION_SYS_REQ_PRESSED (KeyOption)) {\r
a9e7937a 352 KeyShiftStateRight |= EFI_SYS_REQ_PRESSED;\r
353 }\r
354\r
5c08e117 355 KeyShiftStateLeft = (KeyShiftStateRight & 0xffffff00) | ((KeyShiftStateRight & 0xff) << 1);\r
356\r
357 InputKey = (EFI_INPUT_KEY *) (((UINT8 *) KeyOption) + sizeof (EFI_KEY_OPTION));\r
358\r
359 Index = 0;\r
360 KeyData = &HotkeyLeft->KeyData[0];\r
361 do {\r
362 //\r
363 // If Key CodeCount is 0, then only KeyData[0] is used;\r
364 // if Key CodeCount is n, then KeyData[0]~KeyData[n-1] are used\r
365 //\r
366 KeyData->Key.ScanCode = InputKey[Index].ScanCode;\r
367 KeyData->Key.UnicodeChar = InputKey[Index].UnicodeChar;\r
368 KeyData->KeyState.KeyShiftState = KeyShiftStateLeft;\r
369\r
370 Index++;\r
371 KeyData++;\r
372 } while (Index < HotkeyLeft->CodeCount);\r
373 InsertTailList (&mHotkeyList, &HotkeyLeft->Link);\r
374\r
375 if (KeyShiftStateLeft != KeyShiftStateRight) {\r
376 //\r
377 // Need an extra hotkey for shift key on right\r
378 //\r
379 HotkeyRight = AllocateCopyPool (sizeof (BDS_HOTKEY_OPTION), HotkeyLeft);\r
380 if (HotkeyRight == NULL) {\r
381 return EFI_OUT_OF_RESOURCES;\r
382 }\r
383\r
384 Index = 0;\r
385 KeyData = &HotkeyRight->KeyData[0];\r
386 do {\r
387 //\r
388 // Key.ScanCode and Key.UnicodeChar have already been initialized,\r
389 // only need to update KeyState.KeyShiftState\r
390 //\r
391 KeyData->KeyState.KeyShiftState = KeyShiftStateRight;\r
392\r
393 Index++;\r
394 KeyData++;\r
395 } while (Index < HotkeyRight->CodeCount);\r
396 InsertTailList (&mHotkeyList, &HotkeyRight->Link);\r
397 }\r
398\r
399 return EFI_SUCCESS;\r
400}\r
401\r
ad481b0b
RN
402/**\r
403 Return TRUE when the variable pointed by Name and Guid is a Key#### variable.\r
404\r
405 @param Name The name of the variable.\r
406 @param Guid The GUID of the variable.\r
407 @param OptionNumber Return the option number parsed from the Name.\r
408\r
409 @retval TRUE The variable pointed by Name and Guid is a Key#### variable.\r
410 @retval FALSE The variable pointed by Name and Guid isn't a Key#### variable.\r
411**/\r
412BOOLEAN\r
413IsKeyOptionVariable (\r
414 CHAR16 *Name,\r
415 EFI_GUID *Guid,\r
416 UINT16 *OptionNumber\r
417 )\r
418{\r
419 UINTN Index;\r
420 \r
421 if (!CompareGuid (Guid, &gEfiGlobalVariableGuid) ||\r
39b36547 422 (StrSize (Name) != sizeof (L"Key####")) ||\r
ad481b0b
RN
423 (StrnCmp (Name, L"Key", 3) != 0)\r
424 ) {\r
425 return FALSE;\r
426 }\r
427\r
428 *OptionNumber = 0;\r
429 for (Index = 3; Index < 7; Index++) {\r
430 if ((Name[Index] >= L'0') && (Name[Index] <= L'9')) {\r
431 *OptionNumber = *OptionNumber * 10 + Name[Index] - L'0';\r
432 } else if ((Name[Index] >= L'A') && (Name[Index] <= L'F')) {\r
433 *OptionNumber = *OptionNumber * 10 + Name[Index] - L'A';\r
434 } else {\r
435 return FALSE;\r
436 }\r
437 }\r
438\r
439 return TRUE;\r
440}\r
441\r
442/**\r
443 Return an array of key option numbers.\r
444\r
445 @param Count Return the count of key option numbers.\r
446\r
447 @return UINT16* Pointer to an array of key option numbers;\r
448**/\r
449UINT16 *\r
450EFIAPI\r
451HotkeyGetOptionNumbers (\r
452 OUT UINTN *Count\r
453 )\r
454{\r
455 EFI_STATUS Status;\r
456 UINTN Index;\r
457 CHAR16 *Name;\r
458 EFI_GUID Guid;\r
459 UINTN NameSize;\r
460 UINTN NewNameSize;\r
461 UINT16 *OptionNumbers;\r
462 UINT16 OptionNumber;\r
463\r
464 if (Count == NULL) {\r
465 return NULL;\r
466 }\r
467\r
468 *Count = 0;\r
469 OptionNumbers = NULL;\r
470\r
471 NameSize = sizeof (CHAR16);\r
472 Name = AllocateZeroPool (NameSize);\r
5077d4e5 473 ASSERT (Name != NULL);\r
ad481b0b
RN
474 while (TRUE) {\r
475 NewNameSize = NameSize;\r
476 Status = gRT->GetNextVariableName (&NewNameSize, Name, &Guid);\r
477 if (Status == EFI_BUFFER_TOO_SMALL) {\r
478 Name = ReallocatePool (NameSize, NewNameSize, Name);\r
5077d4e5 479 ASSERT (Name != NULL);\r
ad481b0b
RN
480 Status = gRT->GetNextVariableName (&NewNameSize, Name, &Guid);\r
481 NameSize = NewNameSize;\r
482 }\r
483\r
484 if (Status == EFI_NOT_FOUND) {\r
485 break;\r
486 }\r
487 ASSERT_EFI_ERROR (Status);\r
488\r
489 if (IsKeyOptionVariable (Name ,&Guid, &OptionNumber)) {\r
490 OptionNumbers = ReallocatePool (\r
491 *Count * sizeof (UINT16),\r
492 (*Count + 1) * sizeof (UINT16),\r
493 OptionNumbers\r
494 );\r
5077d4e5 495 ASSERT (OptionNumbers != NULL);\r
ad481b0b
RN
496 for (Index = 0; Index < *Count; Index++) {\r
497 if (OptionNumber < OptionNumbers[Index]) {\r
498 break;\r
499 }\r
500 }\r
501 CopyMem (&OptionNumbers[Index + 1], &OptionNumbers[Index], (*Count - Index) * sizeof (UINT16));\r
502 OptionNumbers[Index] = OptionNumber;\r
503 (*Count)++;\r
504 }\r
505 }\r
506\r
507 FreePool (Name);\r
508\r
509 return OptionNumbers;\r
510}\r
511\r
5c08e117 512/**\r
513\r
514 Process all the "Key####" variables, associate Hotkeys with corresponding Boot Options.\r
515\r
516 @retval EFI_SUCCESS Hotkey services successfully initialized.\r
5c08e117 517**/\r
518EFI_STATUS\r
519InitializeHotkeyService (\r
520 VOID\r
521 )\r
522{\r
523 EFI_STATUS Status;\r
524 UINT32 BootOptionSupport;\r
ad481b0b
RN
525 UINT16 *KeyOptionNumbers;\r
526 UINTN KeyOptionCount;\r
5c08e117 527 UINTN Index;\r
ad481b0b 528 CHAR16 KeyOptionName[8];\r
5c08e117 529 EFI_KEY_OPTION *KeyOption;\r
530\r
531 //\r
0a57b959 532 // Export our capability - EFI_BOOT_OPTION_SUPPORT_KEY and EFI_BOOT_OPTION_SUPPORT_APP.\r
a9e7937a 533 // with maximum number of key presses of 3\r
0a57b959 534 // Do not report the hotkey capability if PcdConInConnectOnDemand is enabled.\r
5c08e117 535 //\r
0a57b959 536 BootOptionSupport = EFI_BOOT_OPTION_SUPPORT_APP;\r
537 if (!PcdGetBool (PcdConInConnectOnDemand)) {\r
538 BootOptionSupport |= EFI_BOOT_OPTION_SUPPORT_KEY;\r
539 SET_BOOT_OPTION_SUPPORT_KEY_COUNT (BootOptionSupport, 3);\r
540 }\r
541\r
5c08e117 542 Status = gRT->SetVariable (\r
543 L"BootOptionSupport",\r
544 &gEfiGlobalVariableGuid,\r
a9e7937a 545 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
5c08e117 546 sizeof (UINT32),\r
547 &BootOptionSupport\r
548 );\r
ad481b0b 549 ASSERT_EFI_ERROR (Status);\r
5c08e117 550\r
ad481b0b
RN
551 KeyOptionNumbers = HotkeyGetOptionNumbers (&KeyOptionCount);\r
552 for (Index = 0; Index < KeyOptionCount; Index ++) {\r
553 UnicodeSPrint (KeyOptionName, sizeof (KeyOptionName), L"Key%04x", KeyOptionNumbers[Index]);\r
f52be04a 554 GetEfiGlobalVariable2 (KeyOptionName, (VOID **) &KeyOption, NULL);\r
ad481b0b
RN
555 ASSERT (KeyOption != NULL);\r
556 if (IsKeyOptionValid (KeyOption)) {\r
5c08e117 557 HotkeyInsertList (KeyOption);\r
558 }\r
ad481b0b
RN
559 FreePool (KeyOption);\r
560 }\r
561\r
562 if (KeyOptionNumbers != NULL) {\r
563 FreePool (KeyOptionNumbers);\r
5c08e117 564 }\r
565\r
566 //\r
567 // Register Protocol notify for Hotkey service\r
568 //\r
569 Status = gBS->CreateEvent (\r
570 EVT_NOTIFY_SIGNAL,\r
571 TPL_CALLBACK,\r
572 HotkeyEvent,\r
573 NULL,\r
574 &mHotkeyEvent\r
575 );\r
576 ASSERT_EFI_ERROR (Status);\r
577\r
578 //\r
579 // Register for protocol notifications on this event\r
580 //\r
581 Status = gBS->RegisterProtocolNotify (\r
582 &gEfiSimpleTextInputExProtocolGuid,\r
583 mHotkeyEvent,\r
584 &mHotkeyRegistration\r
585 );\r
586 ASSERT_EFI_ERROR (Status);\r
587\r
588 return Status;\r
589}\r
590\r