]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c
MdePkg/HiiImageEx: Fix incorrect parameter type in GetImageInfo()
[mirror_edk2.git] / MdeModulePkg / Universal / DriverSampleDxe / DriverSample.c
... / ...
CommitLineData
1/** @file\r
2This is an example of how a driver might export data to the HII protocol to be\r
3later utilized by the Setup Protocol\r
4\r
5Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>\r
6This program and the accompanying materials\r
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\r
17#include "DriverSample.h"\r
18\r
19#define DISPLAY_ONLY_MY_ITEM 0x0002\r
20\r
21CHAR16 VariableName[] = L"MyIfrNVData";\r
22CHAR16 MyEfiVar[] = L"MyEfiVar";\r
23EFI_HANDLE DriverHandle[2] = {NULL, NULL};\r
24DRIVER_SAMPLE_PRIVATE_DATA *mPrivateData = NULL;\r
25EFI_EVENT mEvent;\r
26\r
27HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath0 = {\r
28 {\r
29 {\r
30 HARDWARE_DEVICE_PATH,\r
31 HW_VENDOR_DP,\r
32 {\r
33 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
34 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
35 }\r
36 },\r
37 DRIVER_SAMPLE_FORMSET_GUID\r
38 },\r
39 {\r
40 END_DEVICE_PATH_TYPE,\r
41 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
42 {\r
43 (UINT8) (END_DEVICE_PATH_LENGTH),\r
44 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
45 }\r
46 }\r
47};\r
48\r
49HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath1 = {\r
50 {\r
51 {\r
52 HARDWARE_DEVICE_PATH,\r
53 HW_VENDOR_DP,\r
54 {\r
55 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
56 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
57 }\r
58 },\r
59 DRIVER_SAMPLE_INVENTORY_GUID\r
60 },\r
61 {\r
62 END_DEVICE_PATH_TYPE,\r
63 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
64 {\r
65 (UINT8) (END_DEVICE_PATH_LENGTH),\r
66 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
67 }\r
68 }\r
69};\r
70\r
71/**\r
72 Set value of a data element in an Array by its Index.\r
73\r
74 @param Array The data array.\r
75 @param Type Type of the data in this array.\r
76 @param Index Zero based index for data in this array.\r
77 @param Value The value to be set.\r
78\r
79**/\r
80VOID\r
81SetArrayData (\r
82 IN VOID *Array,\r
83 IN UINT8 Type,\r
84 IN UINTN Index,\r
85 IN UINT64 Value\r
86 )\r
87{\r
88\r
89 ASSERT (Array != NULL);\r
90\r
91 switch (Type) {\r
92 case EFI_IFR_TYPE_NUM_SIZE_8:\r
93 *(((UINT8 *) Array) + Index) = (UINT8) Value;\r
94 break;\r
95\r
96 case EFI_IFR_TYPE_NUM_SIZE_16:\r
97 *(((UINT16 *) Array) + Index) = (UINT16) Value;\r
98 break;\r
99\r
100 case EFI_IFR_TYPE_NUM_SIZE_32:\r
101 *(((UINT32 *) Array) + Index) = (UINT32) Value;\r
102 break;\r
103\r
104 case EFI_IFR_TYPE_NUM_SIZE_64:\r
105 *(((UINT64 *) Array) + Index) = (UINT64) Value;\r
106 break;\r
107\r
108 default:\r
109 break;\r
110 }\r
111}\r
112\r
113/**\r
114 Add empty function for event process function.\r
115\r
116 @param Event The Event need to be process\r
117 @param Context The context of the event.\r
118\r
119**/\r
120VOID\r
121EFIAPI\r
122DriverSampleInternalEmptyFunction (\r
123 IN EFI_EVENT Event,\r
124 IN VOID *Context\r
125 )\r
126{\r
127}\r
128\r
129/**\r
130 Notification function for keystrokes.\r
131\r
132 @param[in] KeyData The key that was pressed.\r
133\r
134 @retval EFI_SUCCESS The operation was successful.\r
135**/\r
136EFI_STATUS\r
137EFIAPI\r
138NotificationFunction(\r
139 IN EFI_KEY_DATA *KeyData\r
140 )\r
141{\r
142 gBS->SignalEvent (mEvent);\r
143 \r
144 return EFI_SUCCESS;\r
145}\r
146\r
147/**\r
148 Function to start monitoring for CTRL-C using SimpleTextInputEx. \r
149\r
150 @retval EFI_SUCCESS The feature is enabled.\r
151 @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.\r
152**/\r
153EFI_STATUS\r
154EFIAPI\r
155InternalStartMonitor(\r
156 VOID\r
157 )\r
158{\r
159 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleEx;\r
160 EFI_KEY_DATA KeyData;\r
161 EFI_STATUS Status;\r
162 EFI_HANDLE *Handles;\r
163 UINTN HandleCount;\r
164 UINTN HandleIndex;\r
165 EFI_HANDLE NotifyHandle;\r
166\r
167 Status = gBS->LocateHandleBuffer (\r
168 ByProtocol,\r
169 &gEfiSimpleTextInputExProtocolGuid,\r
170 NULL,\r
171 &HandleCount,\r
172 &Handles\r
173 );\r
174 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {\r
175 Status = gBS->HandleProtocol (Handles[HandleIndex], &gEfiSimpleTextInputExProtocolGuid, (VOID **) &SimpleEx);\r
176 ASSERT_EFI_ERROR (Status);\r
177\r
178 KeyData.KeyState.KeyToggleState = 0;\r
179 KeyData.Key.ScanCode = 0;\r
180 KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED;\r
181 KeyData.Key.UnicodeChar = L'c';\r
182\r
183 Status = SimpleEx->RegisterKeyNotify(\r
184 SimpleEx,\r
185 &KeyData,\r
186 NotificationFunction,\r
187 &NotifyHandle);\r
188 if (EFI_ERROR (Status)) {\r
189 break;\r
190 }\r
191 \r
192 KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;\r
193 Status = SimpleEx->RegisterKeyNotify(\r
194 SimpleEx,\r
195 &KeyData,\r
196 NotificationFunction,\r
197 &NotifyHandle);\r
198 if (EFI_ERROR (Status)) {\r
199 break;\r
200 }\r
201 }\r
202\r
203 return EFI_SUCCESS;\r
204}\r
205\r
206/**\r
207 Function to stop monitoring for CTRL-C using SimpleTextInputEx. \r
208\r
209 @retval EFI_SUCCESS The feature is enabled.\r
210 @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.\r
211**/\r
212EFI_STATUS\r
213EFIAPI\r
214InternalStopMonitor(\r
215 VOID\r
216 )\r
217{\r
218 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleEx;\r
219 EFI_STATUS Status;\r
220 EFI_HANDLE *Handles;\r
221 EFI_KEY_DATA KeyData; \r
222 UINTN HandleCount;\r
223 UINTN HandleIndex;\r
224 EFI_HANDLE NotifyHandle;\r
225\r
226 Status = gBS->LocateHandleBuffer (\r
227 ByProtocol,\r
228 &gEfiSimpleTextInputExProtocolGuid,\r
229 NULL,\r
230 &HandleCount,\r
231 &Handles\r
232 );\r
233 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {\r
234 Status = gBS->HandleProtocol (Handles[HandleIndex], &gEfiSimpleTextInputExProtocolGuid, (VOID **) &SimpleEx);\r
235 ASSERT_EFI_ERROR (Status);\r
236\r
237 KeyData.KeyState.KeyToggleState = 0;\r
238 KeyData.Key.ScanCode = 0;\r
239 KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED;\r
240 KeyData.Key.UnicodeChar = L'c';\r
241\r
242 Status = SimpleEx->RegisterKeyNotify(\r
243 SimpleEx,\r
244 &KeyData,\r
245 NotificationFunction,\r
246 &NotifyHandle);\r
247 if (!EFI_ERROR (Status)) {\r
248 Status = SimpleEx->UnregisterKeyNotify (SimpleEx, NotifyHandle);\r
249 }\r
250\r
251 KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;\r
252 Status = SimpleEx->RegisterKeyNotify(\r
253 SimpleEx,\r
254 &KeyData,\r
255 NotificationFunction,\r
256 &NotifyHandle);\r
257 if (!EFI_ERROR (Status)) {\r
258 Status = SimpleEx->UnregisterKeyNotify (SimpleEx, NotifyHandle);\r
259 }\r
260 }\r
261 return EFI_SUCCESS;\r
262}\r
263\r
264\r
265/**\r
266 Encode the password using a simple algorithm.\r
267\r
268 @param Password The string to be encoded.\r
269 @param MaxSize The size of the string.\r
270\r
271**/\r
272VOID\r
273EncodePassword (\r
274 IN CHAR16 *Password,\r
275 IN UINTN MaxSize\r
276 )\r
277{\r
278 UINTN Index;\r
279 UINTN Loop;\r
280 CHAR16 *Buffer;\r
281 CHAR16 *Key;\r
282\r
283 Key = L"MAR10648567";\r
284 Buffer = AllocateZeroPool (MaxSize);\r
285 ASSERT (Buffer != NULL);\r
286\r
287 for (Index = 0; Key[Index] != 0; Index++) {\r
288 for (Loop = 0; Loop < (UINT8) (MaxSize / 2); Loop++) {\r
289 Buffer[Loop] = (CHAR16) (Password[Loop] ^ Key[Index]);\r
290 }\r
291 }\r
292\r
293 CopyMem (Password, Buffer, MaxSize);\r
294\r
295 FreePool (Buffer);\r
296 return ;\r
297}\r
298\r
299/**\r
300 Validate the user's password.\r
301\r
302 @param PrivateData This driver's private context data.\r
303 @param StringId The user's input.\r
304\r
305 @retval EFI_SUCCESS The user's input matches the password.\r
306 @retval EFI_NOT_READY The user's input does not match the password.\r
307**/\r
308EFI_STATUS\r
309ValidatePassword (\r
310 IN DRIVER_SAMPLE_PRIVATE_DATA *PrivateData,\r
311 IN EFI_STRING_ID StringId\r
312 )\r
313{\r
314 EFI_STATUS Status;\r
315 UINTN Index;\r
316 UINTN BufferSize;\r
317 UINTN PasswordMaxSize;\r
318 CHAR16 *Password;\r
319 CHAR16 *EncodedPassword;\r
320 BOOLEAN OldPassword;\r
321\r
322 //\r
323 // Get encoded password first\r
324 //\r
325 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
326 Status = gRT->GetVariable (\r
327 VariableName,\r
328 &gDriverSampleFormSetGuid,\r
329 NULL,\r
330 &BufferSize,\r
331 &PrivateData->Configuration\r
332 );\r
333 if (EFI_ERROR (Status)) {\r
334 //\r
335 // Old password not exist, prompt for new password\r
336 //\r
337 return EFI_SUCCESS;\r
338 }\r
339\r
340 OldPassword = FALSE;\r
341 PasswordMaxSize = sizeof (PrivateData->Configuration.WhatIsThePassword2);\r
342 //\r
343 // Check whether we have any old password set\r
344 //\r
345 for (Index = 0; Index < PasswordMaxSize / sizeof (UINT16); Index++) {\r
346 if (PrivateData->Configuration.WhatIsThePassword2[Index] != 0) {\r
347 OldPassword = TRUE;\r
348 break;\r
349 }\r
350 }\r
351 if (!OldPassword) {\r
352 //\r
353 // Old password not exist, return EFI_SUCCESS to prompt for new password\r
354 //\r
355 return EFI_SUCCESS;\r
356 }\r
357\r
358 //\r
359 // Get user input password\r
360 //\r
361 Password = HiiGetString (PrivateData->HiiHandle[0], StringId, NULL);\r
362 if (Password == NULL) {\r
363 return EFI_NOT_READY;\r
364 }\r
365 if (StrSize (Password) > PasswordMaxSize) {\r
366 FreePool (Password);\r
367 return EFI_NOT_READY;\r
368 }\r
369\r
370 //\r
371 // Validate old password\r
372 //\r
373 EncodedPassword = AllocateZeroPool (PasswordMaxSize);\r
374 ASSERT (EncodedPassword != NULL);\r
375 StrnCpyS (EncodedPassword, PasswordMaxSize / sizeof (CHAR16), Password, StrLen (Password));\r
376 EncodePassword (EncodedPassword, StrLen (EncodedPassword) * sizeof (CHAR16));\r
377 if (CompareMem (EncodedPassword, PrivateData->Configuration.WhatIsThePassword2, PasswordMaxSize) != 0) {\r
378 //\r
379 // Old password mismatch, return EFI_NOT_READY to prompt for error message\r
380 //\r
381 Status = EFI_NOT_READY;\r
382 } else {\r
383 Status = EFI_SUCCESS;\r
384 }\r
385\r
386 FreePool (Password);\r
387 FreePool (EncodedPassword);\r
388\r
389 return Status;\r
390}\r
391\r
392/**\r
393 Encode the password using a simple algorithm.\r
394\r
395 @param PrivateData This driver's private context data.\r
396 @param StringId The password from User.\r
397\r
398 @retval EFI_SUCESS The operation is successful.\r
399 @return Other value if gRT->SetVariable () fails.\r
400\r
401**/\r
402EFI_STATUS\r
403SetPassword (\r
404 IN DRIVER_SAMPLE_PRIVATE_DATA *PrivateData,\r
405 IN EFI_STRING_ID StringId\r
406 )\r
407{\r
408 EFI_STATUS Status;\r
409 CHAR16 *Password;\r
410 CHAR16 *TempPassword;\r
411 UINTN PasswordSize;\r
412 DRIVER_SAMPLE_CONFIGURATION *Configuration;\r
413 UINTN BufferSize;\r
414\r
415 //\r
416 // Get Buffer Storage data from EFI variable\r
417 //\r
418 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
419 Status = gRT->GetVariable (\r
420 VariableName,\r
421 &gDriverSampleFormSetGuid,\r
422 NULL,\r
423 &BufferSize,\r
424 &PrivateData->Configuration\r
425 );\r
426 if (EFI_ERROR (Status)) {\r
427 return Status;\r
428 }\r
429\r
430 //\r
431 // Get user input password\r
432 //\r
433 Password = PrivateData->Configuration.WhatIsThePassword2;\r
434 PasswordSize = sizeof (PrivateData->Configuration.WhatIsThePassword2);\r
435 ZeroMem (Password, PasswordSize);\r
436\r
437 TempPassword = HiiGetString (PrivateData->HiiHandle[0], StringId, NULL);\r
438 if (TempPassword == NULL) {\r
439 return EFI_NOT_READY;\r
440 }\r
441 if (StrSize (TempPassword) > PasswordSize) {\r
442 FreePool (TempPassword);\r
443 return EFI_NOT_READY;\r
444 }\r
445 StrnCpyS (Password, PasswordSize / sizeof (CHAR16), TempPassword, StrLen (TempPassword));\r
446 FreePool (TempPassword);\r
447\r
448 //\r
449 // Retrive uncommitted data from Browser\r
450 //\r
451 Configuration = AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION));\r
452 ASSERT (Configuration != NULL);\r
453 if (HiiGetBrowserData (&gDriverSampleFormSetGuid, VariableName, sizeof (DRIVER_SAMPLE_CONFIGURATION), (UINT8 *) Configuration)) {\r
454 //\r
455 // Update password's clear text in the screen\r
456 //\r
457 CopyMem (Configuration->PasswordClearText, Password, StrSize (Password));\r
458\r
459 //\r
460 // Update uncommitted data of Browser\r
461 //\r
462 HiiSetBrowserData (\r
463 &gDriverSampleFormSetGuid,\r
464 VariableName,\r
465 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
466 (UINT8 *) Configuration,\r
467 NULL\r
468 );\r
469 }\r
470\r
471 //\r
472 // Free Configuration Buffer\r
473 //\r
474 FreePool (Configuration);\r
475\r
476\r
477 //\r
478 // Set password\r
479 //\r
480 EncodePassword (Password, StrLen (Password) * 2);\r
481 Status = gRT->SetVariable(\r
482 VariableName,\r
483 &gDriverSampleFormSetGuid,\r
484 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
485 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
486 &PrivateData->Configuration\r
487 );\r
488 return Status;\r
489}\r
490\r
491/**\r
492 Update names of Name/Value storage to current language.\r
493\r
494 @param PrivateData Points to the driver private data.\r
495\r
496 @retval EFI_SUCCESS All names are successfully updated.\r
497 @retval EFI_NOT_FOUND Failed to get Name from HII database.\r
498\r
499**/\r
500EFI_STATUS\r
501LoadNameValueNames (\r
502 IN DRIVER_SAMPLE_PRIVATE_DATA *PrivateData\r
503 )\r
504{\r
505 UINTN Index;\r
506\r
507 //\r
508 // Get Name/Value name string of current language\r
509 //\r
510 for (Index = 0; Index < NAME_VALUE_NAME_NUMBER; Index++) {\r
511 PrivateData->NameValueName[Index] = HiiGetString (\r
512 PrivateData->HiiHandle[0],\r
513 PrivateData->NameStringId[Index],\r
514 NULL\r
515 );\r
516 if (PrivateData->NameValueName[Index] == NULL) {\r
517 return EFI_NOT_FOUND;\r
518 }\r
519 }\r
520\r
521 return EFI_SUCCESS;\r
522}\r
523\r
524\r
525/**\r
526 Get the value of <Number> in <BlockConfig> format, i.e. the value of OFFSET\r
527 or WIDTH or VALUE.\r
528 <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number>\r
529\r
530 This is a internal function.\r
531\r
532 @param StringPtr String in <BlockConfig> format and points to the\r
533 first character of <Number>.\r
534 @param Number The output value. Caller takes the responsibility\r
535 to free memory.\r
536 @param Len Length of the <Number>, in characters.\r
537\r
538 @retval EFI_OUT_OF_RESOURCES Insufficient resources to store neccessary\r
539 structures.\r
540 @retval EFI_SUCCESS Value of <Number> is outputted in Number\r
541 successfully.\r
542\r
543**/\r
544EFI_STATUS\r
545GetValueOfNumber (\r
546 IN EFI_STRING StringPtr,\r
547 OUT UINT8 **Number,\r
548 OUT UINTN *Len\r
549 )\r
550{\r
551 EFI_STRING TmpPtr;\r
552 UINTN Length;\r
553 EFI_STRING Str;\r
554 UINT8 *Buf;\r
555 EFI_STATUS Status;\r
556 UINT8 DigitUint8;\r
557 UINTN Index;\r
558 CHAR16 TemStr[2];\r
559\r
560 if (StringPtr == NULL || *StringPtr == L'\0' || Number == NULL || Len == NULL) {\r
561 return EFI_INVALID_PARAMETER;\r
562 }\r
563\r
564 Buf = NULL;\r
565\r
566 TmpPtr = StringPtr;\r
567 while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
568 StringPtr++;\r
569 }\r
570 *Len = StringPtr - TmpPtr;\r
571 Length = *Len + 1;\r
572\r
573 Str = (EFI_STRING) AllocateZeroPool (Length * sizeof (CHAR16));\r
574 if (Str == NULL) {\r
575 Status = EFI_OUT_OF_RESOURCES;\r
576 goto Exit;\r
577 }\r
578 CopyMem (Str, TmpPtr, *Len * sizeof (CHAR16));\r
579 *(Str + *Len) = L'\0';\r
580\r
581 Length = (Length + 1) / 2;\r
582 Buf = (UINT8 *) AllocateZeroPool (Length);\r
583 if (Buf == NULL) {\r
584 Status = EFI_OUT_OF_RESOURCES;\r
585 goto Exit;\r
586 }\r
587 \r
588 Length = *Len;\r
589 ZeroMem (TemStr, sizeof (TemStr));\r
590 for (Index = 0; Index < Length; Index ++) {\r
591 TemStr[0] = Str[Length - Index - 1];\r
592 DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
593 if ((Index & 1) == 0) {\r
594 Buf [Index/2] = DigitUint8;\r
595 } else {\r
596 Buf [Index/2] = (UINT8) ((DigitUint8 << 4) + Buf [Index/2]);\r
597 }\r
598 }\r
599\r
600 *Number = Buf;\r
601 Status = EFI_SUCCESS;\r
602\r
603Exit:\r
604 if (Str != NULL) {\r
605 FreePool (Str);\r
606 }\r
607\r
608 return Status;\r
609}\r
610\r
611/**\r
612 Create altcfg string. \r
613\r
614 @param Result The request result string.\r
615 @param ConfigHdr The request head info. <ConfigHdr> format.\r
616 @param Offset The offset of the parameter int he structure.\r
617 @param Width The width of the parameter.\r
618\r
619\r
620 @retval The string with altcfg info append at the end.\r
621**/\r
622EFI_STRING \r
623CreateAltCfgString (\r
624 IN EFI_STRING Result,\r
625 IN EFI_STRING ConfigHdr,\r
626 IN UINTN Offset,\r
627 IN UINTN Width\r
628 )\r
629{\r
630 EFI_STRING StringPtr;\r
631 EFI_STRING TmpStr;\r
632 UINTN NewLen;\r
633\r
634 NewLen = StrLen (Result);\r
635 //\r
636 // String Len = ConfigResp + AltConfig + AltConfig + 1("\0")\r
637 //\r
638 NewLen = (NewLen + ((1 + StrLen (ConfigHdr) + 8 + 4) + (8 + 4 + 7 + 4 + 7 + 4)) * 2 + 1) * sizeof (CHAR16);\r
639 StringPtr = AllocateZeroPool (NewLen);\r
640 if (StringPtr == NULL) {\r
641 return NULL;\r
642 }\r
643\r
644 TmpStr = StringPtr;\r
645 if (Result != NULL) {\r
646 StrCpyS (StringPtr, NewLen / sizeof (CHAR16), Result);\r
647 StringPtr += StrLen (Result); \r
648 FreePool (Result);\r
649 }\r
650 \r
651 UnicodeSPrint (\r
652 StringPtr, \r
653 (1 + StrLen (ConfigHdr) + 8 + 4 + 1) * sizeof (CHAR16), \r
654 L"&%s&ALTCFG=%04x", \r
655 ConfigHdr, \r
656 EFI_HII_DEFAULT_CLASS_STANDARD\r
657 );\r
658 StringPtr += StrLen (StringPtr);\r
659\r
660 UnicodeSPrint (\r
661 StringPtr, \r
662 (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16),\r
663 L"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x", \r
664 Offset, \r
665 Width,\r
666 DEFAULT_CLASS_STANDARD_VALUE\r
667 );\r
668 StringPtr += StrLen (StringPtr); \r
669\r
670 UnicodeSPrint (\r
671 StringPtr, \r
672 (1 + StrLen (ConfigHdr) + 8 + 4 + 1) * sizeof (CHAR16), \r
673 L"&%s&ALTCFG=%04x", \r
674 ConfigHdr, \r
675 EFI_HII_DEFAULT_CLASS_MANUFACTURING\r
676 );\r
677 StringPtr += StrLen (StringPtr);\r
678\r
679 UnicodeSPrint (\r
680 StringPtr, \r
681 (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16),\r
682 L"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x", \r
683 Offset, \r
684 Width,\r
685 DEFAULT_CLASS_MANUFACTURING_VALUE\r
686 );\r
687 StringPtr += StrLen (StringPtr); \r
688\r
689 return TmpStr;\r
690}\r
691\r
692/**\r
693 Check whether need to add the altcfg string. if need to add, add the altcfg \r
694 string.\r
695\r
696 @param RequestResult The request result string.\r
697 @param ConfigRequestHdr The request head info. <ConfigHdr> format.\r
698\r
699**/\r
700VOID \r
701AppendAltCfgString (\r
702 IN OUT EFI_STRING *RequestResult,\r
703 IN EFI_STRING ConfigRequestHdr\r
704 )\r
705{\r
706 EFI_STRING StringPtr;\r
707 UINTN Length;\r
708 UINT8 *TmpBuffer;\r
709 UINTN Offset;\r
710 UINTN Width;\r
711 UINTN BlockSize;\r
712 UINTN ValueOffset;\r
713 UINTN ValueWidth;\r
714 EFI_STATUS Status;\r
715\r
716 TmpBuffer = NULL;\r
717 StringPtr = *RequestResult;\r
718 StringPtr = StrStr (StringPtr, L"OFFSET");\r
719 BlockSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
720 ValueOffset = OFFSET_OF (DRIVER_SAMPLE_CONFIGURATION, GetDefaultValueFromAccess);\r
721 ValueWidth = sizeof (((DRIVER_SAMPLE_CONFIGURATION *)0)->GetDefaultValueFromAccess);\r
722\r
723 if (StringPtr == NULL) {\r
724 return;\r
725 }\r
726\r
727 while (*StringPtr != 0 && StrnCmp (StringPtr, L"OFFSET=", StrLen (L"OFFSET=")) == 0) {\r
728 StringPtr += StrLen (L"OFFSET=");\r
729 //\r
730 // Get Offset\r
731 //\r
732 Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
733 if (EFI_ERROR (Status)) {\r
734 return;\r
735 }\r
736 Offset = 0;\r
737 CopyMem (\r
738 &Offset,\r
739 TmpBuffer,\r
740 (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)\r
741 );\r
742 FreePool (TmpBuffer);\r
743\r
744 StringPtr += Length;\r
745 if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {\r
746 return;\r
747 }\r
748 StringPtr += StrLen (L"&WIDTH=");\r
749\r
750 //\r
751 // Get Width\r
752 //\r
753 Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
754 if (EFI_ERROR (Status)) {\r
755 return;\r
756 }\r
757 Width = 0;\r
758 CopyMem (\r
759 &Width,\r
760 TmpBuffer,\r
761 (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)\r
762 );\r
763 FreePool (TmpBuffer);\r
764\r
765 StringPtr += Length;\r
766 if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) != 0) {\r
767 return;\r
768 }\r
769 StringPtr += StrLen (L"&VALUE=");\r
770\r
771 //\r
772 // Get Value\r
773 //\r
774 Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
775 if (EFI_ERROR (Status)) {\r
776 return;\r
777 }\r
778 StringPtr += Length;\r
779\r
780 //\r
781 // Calculate Value and convert it to hex string.\r
782 //\r
783 if (Offset + Width > BlockSize) {\r
784 return;\r
785 }\r
786\r
787 if (Offset <= ValueOffset && Offset + Width >= ValueOffset + ValueWidth) {\r
788 *RequestResult = CreateAltCfgString(*RequestResult, ConfigRequestHdr, ValueOffset, ValueWidth);\r
789 return;\r
790 }\r
791 }\r
792}\r
793\r
794/**\r
795 This function allows a caller to extract the current configuration for one\r
796 or more named elements from the target driver.\r
797\r
798 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
799 @param Request A null-terminated Unicode string in\r
800 <ConfigRequest> format.\r
801 @param Progress On return, points to a character in the Request\r
802 string. Points to the string's null terminator if\r
803 request was successful. Points to the most recent\r
804 '&' before the first failing name/value pair (or\r
805 the beginning of the string if the failure is in\r
806 the first name/value pair) if the request was not\r
807 successful.\r
808 @param Results A null-terminated Unicode string in\r
809 <ConfigAltResp> format which has all values filled\r
810 in for the names in the Request string. String to\r
811 be allocated by the called function.\r
812\r
813 @retval EFI_SUCCESS The Results is filled with the requested values.\r
814 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
815 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.\r
816 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this\r
817 driver.\r
818\r
819**/\r
820EFI_STATUS\r
821EFIAPI\r
822ExtractConfig (\r
823 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
824 IN CONST EFI_STRING Request,\r
825 OUT EFI_STRING *Progress,\r
826 OUT EFI_STRING *Results\r
827 )\r
828{\r
829 EFI_STATUS Status;\r
830 UINTN BufferSize;\r
831 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;\r
832 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
833 EFI_STRING ConfigRequest;\r
834 EFI_STRING ConfigRequestHdr;\r
835 UINTN Size;\r
836 EFI_STRING Value;\r
837 UINTN ValueStrLen;\r
838 CHAR16 BackupChar;\r
839 CHAR16 *StrPointer;\r
840 BOOLEAN AllocatedRequest;\r
841\r
842 if (Progress == NULL || Results == NULL) {\r
843 return EFI_INVALID_PARAMETER;\r
844 }\r
845 //\r
846 // Initialize the local variables.\r
847 //\r
848 ConfigRequestHdr = NULL;\r
849 ConfigRequest = NULL;\r
850 Size = 0;\r
851 *Progress = Request;\r
852 AllocatedRequest = FALSE;\r
853\r
854 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
855 HiiConfigRouting = PrivateData->HiiConfigRouting;\r
856\r
857 //\r
858 // Get Buffer Storage data from EFI variable.\r
859 // Try to get the current setting from variable.\r
860 //\r
861 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
862 Status = gRT->GetVariable (\r
863 VariableName,\r
864 &gDriverSampleFormSetGuid,\r
865 NULL,\r
866 &BufferSize,\r
867 &PrivateData->Configuration\r
868 );\r
869 if (EFI_ERROR (Status)) {\r
870 return EFI_NOT_FOUND;\r
871 }\r
872\r
873 if (Request == NULL) {\r
874 //\r
875 // Request is set to NULL, construct full request string.\r
876 //\r
877\r
878 //\r
879 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
880 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
881 //\r
882 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, PrivateData->DriverHandle[0]);\r
883 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
884 ConfigRequest = AllocateZeroPool (Size);\r
885 ASSERT (ConfigRequest != NULL);\r
886 AllocatedRequest = TRUE;\r
887 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
888 FreePool (ConfigRequestHdr);\r
889 ConfigRequestHdr = NULL;\r
890 } else {\r
891 //\r
892 // Check routing data in <ConfigHdr>.\r
893 // Note: if only one Storage is used, then this checking could be skipped.\r
894 //\r
895 if (!HiiIsConfigHdrMatch (Request, &gDriverSampleFormSetGuid, NULL)) {\r
896 return EFI_NOT_FOUND;\r
897 }\r
898 //\r
899 // Check whether request for EFI Varstore. EFI varstore get data\r
900 // through hii database, not support in this path.\r
901 //\r
902 if (HiiIsConfigHdrMatch(Request, &gDriverSampleFormSetGuid, MyEfiVar)) {\r
903 return EFI_UNSUPPORTED;\r
904 }\r
905 //\r
906 // Set Request to the unified request string.\r
907 //\r
908 ConfigRequest = Request;\r
909 //\r
910 // Check whether Request includes Request Element.\r
911 //\r
912 if (StrStr (Request, L"OFFSET") == NULL) {\r
913 //\r
914 // Check Request Element does exist in Reques String\r
915 //\r
916 StrPointer = StrStr (Request, L"PATH");\r
917 if (StrPointer == NULL) {\r
918 return EFI_INVALID_PARAMETER;\r
919 }\r
920 if (StrStr (StrPointer, L"&") == NULL) {\r
921 Size = (StrLen (Request) + 32 + 1) * sizeof (CHAR16);\r
922 ConfigRequest = AllocateZeroPool (Size);\r
923 ASSERT (ConfigRequest != NULL);\r
924 AllocatedRequest = TRUE;\r
925 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", Request, (UINT64)BufferSize);\r
926 }\r
927 }\r
928 }\r
929\r
930 //\r
931 // Check if requesting Name/Value storage\r
932 //\r
933 if (StrStr (ConfigRequest, L"OFFSET") == NULL) {\r
934 //\r
935 // Update Name/Value storage Names\r
936 //\r
937 Status = LoadNameValueNames (PrivateData);\r
938 if (EFI_ERROR (Status)) {\r
939 return Status;\r
940 }\r
941\r
942 //\r
943 // Allocate memory for <ConfigResp>, e.g. Name0=0x11, Name1=0x1234, Name2="ABCD"\r
944 // <Request> ::=<ConfigHdr>&Name0&Name1&Name2\r
945 // <ConfigResp>::=<ConfigHdr>&Name0=11&Name1=1234&Name2=0041004200430044\r
946 //\r
947 BufferSize = (StrLen (ConfigRequest) +\r
948 1 + sizeof (PrivateData->Configuration.NameValueVar0) * 2 +\r
949 1 + sizeof (PrivateData->Configuration.NameValueVar1) * 2 +\r
950 1 + sizeof (PrivateData->Configuration.NameValueVar2) * 2 + 1) * sizeof (CHAR16);\r
951 *Results = AllocateZeroPool (BufferSize);\r
952 ASSERT (*Results != NULL);\r
953 StrCpyS (*Results, BufferSize / sizeof (CHAR16), ConfigRequest);\r
954 Value = *Results;\r
955\r
956 //\r
957 // Append value of NameValueVar0, type is UINT8\r
958 //\r
959 if ((Value = StrStr (*Results, PrivateData->NameValueName[0])) != NULL) {\r
960 Value += StrLen (PrivateData->NameValueName[0]);\r
961 ValueStrLen = ((sizeof (PrivateData->Configuration.NameValueVar0) * 2) + 1);\r
962 CopyMem (Value + ValueStrLen, Value, StrSize (Value));\r
963\r
964 BackupChar = Value[ValueStrLen];\r
965 *Value++ = L'=';\r
966 Value += UnicodeValueToString (\r
967 Value, \r
968 PREFIX_ZERO | RADIX_HEX, \r
969 PrivateData->Configuration.NameValueVar0, \r
970 sizeof (PrivateData->Configuration.NameValueVar0) * 2\r
971 );\r
972 *Value = BackupChar;\r
973 }\r
974\r
975 //\r
976 // Append value of NameValueVar1, type is UINT16\r
977 //\r
978 if ((Value = StrStr (*Results, PrivateData->NameValueName[1])) != NULL) {\r
979 Value += StrLen (PrivateData->NameValueName[1]);\r
980 ValueStrLen = ((sizeof (PrivateData->Configuration.NameValueVar1) * 2) + 1);\r
981 CopyMem (Value + ValueStrLen, Value, StrSize (Value));\r
982\r
983 BackupChar = Value[ValueStrLen];\r
984 *Value++ = L'=';\r
985 Value += UnicodeValueToString (\r
986 Value, \r
987 PREFIX_ZERO | RADIX_HEX, \r
988 PrivateData->Configuration.NameValueVar1, \r
989 sizeof (PrivateData->Configuration.NameValueVar1) * 2\r
990 );\r
991 *Value = BackupChar;\r
992 }\r
993\r
994 //\r
995 // Append value of NameValueVar2, type is CHAR16 *\r
996 //\r
997 if ((Value = StrStr (*Results, PrivateData->NameValueName[2])) != NULL) {\r
998 Value += StrLen (PrivateData->NameValueName[2]);\r
999 ValueStrLen = StrLen (PrivateData->Configuration.NameValueVar2) * 4 + 1;\r
1000 CopyMem (Value + ValueStrLen, Value, StrSize (Value));\r
1001\r
1002 *Value++ = L'=';\r
1003 //\r
1004 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"\r
1005 //\r
1006 StrPointer = (CHAR16 *) PrivateData->Configuration.NameValueVar2;\r
1007 for (; *StrPointer != L'\0'; StrPointer++) {\r
1008 Value += UnicodeValueToString (Value, PREFIX_ZERO | RADIX_HEX, *StrPointer, 4);\r
1009 }\r
1010 }\r
1011 \r
1012 Status = EFI_SUCCESS;\r
1013 } else {\r
1014 //\r
1015 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
1016 //\r
1017 Status = HiiConfigRouting->BlockToConfig (\r
1018 HiiConfigRouting,\r
1019 ConfigRequest,\r
1020 (UINT8 *) &PrivateData->Configuration,\r
1021 BufferSize,\r
1022 Results,\r
1023 Progress\r
1024 );\r
1025 if (!EFI_ERROR (Status)) {\r
1026 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, PrivateData->DriverHandle[0]);\r
1027 AppendAltCfgString(Results, ConfigRequestHdr);\r
1028 }\r
1029 }\r
1030\r
1031 //\r
1032 // Free the allocated config request string.\r
1033 //\r
1034 if (AllocatedRequest) {\r
1035 FreePool (ConfigRequest);\r
1036 }\r
1037\r
1038 if (ConfigRequestHdr != NULL) {\r
1039 FreePool (ConfigRequestHdr);\r
1040 }\r
1041 //\r
1042 // Set Progress string to the original request string.\r
1043 //\r
1044 if (Request == NULL) {\r
1045 *Progress = NULL;\r
1046 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
1047 *Progress = Request + StrLen (Request);\r
1048 }\r
1049\r
1050 return Status;\r
1051}\r
1052\r
1053\r
1054/**\r
1055 This function processes the results of changes in configuration.\r
1056\r
1057 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
1058 @param Configuration A null-terminated Unicode string in <ConfigResp>\r
1059 format.\r
1060 @param Progress A pointer to a string filled in with the offset of\r
1061 the most recent '&' before the first failing\r
1062 name/value pair (or the beginning of the string if\r
1063 the failure is in the first name/value pair) or\r
1064 the terminating NULL if all was successful.\r
1065\r
1066 @retval EFI_SUCCESS The Results is processed successfully.\r
1067 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
1068 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this\r
1069 driver.\r
1070\r
1071**/\r
1072EFI_STATUS\r
1073EFIAPI\r
1074RouteConfig (\r
1075 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
1076 IN CONST EFI_STRING Configuration,\r
1077 OUT EFI_STRING *Progress\r
1078 )\r
1079{\r
1080 EFI_STATUS Status;\r
1081 UINTN BufferSize;\r
1082 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;\r
1083 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
1084 CHAR16 *Value;\r
1085 CHAR16 *StrPtr;\r
1086 CHAR16 TemStr[5];\r
1087 UINT8 *DataBuffer;\r
1088 UINT8 DigitUint8;\r
1089 UINTN Index;\r
1090 CHAR16 *StrBuffer;\r
1091\r
1092 if (Configuration == NULL || Progress == NULL) {\r
1093 return EFI_INVALID_PARAMETER;\r
1094 }\r
1095\r
1096 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
1097 HiiConfigRouting = PrivateData->HiiConfigRouting;\r
1098 *Progress = Configuration;\r
1099\r
1100 //\r
1101 // Check routing data in <ConfigHdr>.\r
1102 // Note: if only one Storage is used, then this checking could be skipped.\r
1103 //\r
1104 if (!HiiIsConfigHdrMatch (Configuration, &gDriverSampleFormSetGuid, NULL)) {\r
1105 return EFI_NOT_FOUND;\r
1106 }\r
1107\r
1108 //\r
1109 // Check whether request for EFI Varstore. EFI varstore get data\r
1110 // through hii database, not support in this path.\r
1111 //\r
1112 if (HiiIsConfigHdrMatch(Configuration, &gDriverSampleFormSetGuid, MyEfiVar)) {\r
1113 return EFI_UNSUPPORTED;\r
1114 }\r
1115\r
1116 //\r
1117 // Get Buffer Storage data from EFI variable\r
1118 //\r
1119 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
1120 Status = gRT->GetVariable (\r
1121 VariableName,\r
1122 &gDriverSampleFormSetGuid,\r
1123 NULL,\r
1124 &BufferSize,\r
1125 &PrivateData->Configuration\r
1126 );\r
1127 if (EFI_ERROR (Status)) {\r
1128 return Status;\r
1129 }\r
1130\r
1131 //\r
1132 // Check if configuring Name/Value storage\r
1133 //\r
1134 if (StrStr (Configuration, L"OFFSET") == NULL) {\r
1135 //\r
1136 // Update Name/Value storage Names\r
1137 //\r
1138 Status = LoadNameValueNames (PrivateData);\r
1139 if (EFI_ERROR (Status)) {\r
1140 return Status;\r
1141 }\r
1142\r
1143 //\r
1144 // Convert value for NameValueVar0\r
1145 //\r
1146 if ((Value = StrStr (Configuration, PrivateData->NameValueName[0])) != NULL) {\r
1147 //\r
1148 // Skip "Name="\r
1149 //\r
1150 Value += StrLen (PrivateData->NameValueName[0]);\r
1151 Value++;\r
1152 //\r
1153 // Get Value String\r
1154 //\r
1155 StrPtr = StrStr (Value, L"&");\r
1156 if (StrPtr == NULL) {\r
1157 StrPtr = Value + StrLen (Value);\r
1158 }\r
1159 //\r
1160 // Convert Value to Buffer data\r
1161 //\r
1162 DataBuffer = (UINT8 *) &PrivateData->Configuration.NameValueVar0;\r
1163 ZeroMem (TemStr, sizeof (TemStr));\r
1164 for (Index = 0, StrPtr --; StrPtr >= Value; StrPtr --, Index ++) {\r
1165 TemStr[0] = *StrPtr;\r
1166 DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
1167 if ((Index & 1) == 0) {\r
1168 DataBuffer [Index/2] = DigitUint8;\r
1169 } else {\r
1170 DataBuffer [Index/2] = (UINT8) ((UINT8) (DigitUint8 << 4) + DataBuffer [Index/2]);\r
1171 }\r
1172 }\r
1173 }\r
1174\r
1175 //\r
1176 // Convert value for NameValueVar1\r
1177 //\r
1178 if ((Value = StrStr (Configuration, PrivateData->NameValueName[1])) != NULL) {\r
1179 //\r
1180 // Skip "Name="\r
1181 //\r
1182 Value += StrLen (PrivateData->NameValueName[1]);\r
1183 Value++;\r
1184 //\r
1185 // Get Value String\r
1186 //\r
1187 StrPtr = StrStr (Value, L"&");\r
1188 if (StrPtr == NULL) {\r
1189 StrPtr = Value + StrLen (Value);\r
1190 }\r
1191 //\r
1192 // Convert Value to Buffer data\r
1193 //\r
1194 DataBuffer = (UINT8 *) &PrivateData->Configuration.NameValueVar1;\r
1195 ZeroMem (TemStr, sizeof (TemStr));\r
1196 for (Index = 0, StrPtr --; StrPtr >= Value; StrPtr --, Index ++) {\r
1197 TemStr[0] = *StrPtr;\r
1198 DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
1199 if ((Index & 1) == 0) {\r
1200 DataBuffer [Index/2] = DigitUint8;\r
1201 } else {\r
1202 DataBuffer [Index/2] = (UINT8) ((UINT8) (DigitUint8 << 4) + DataBuffer [Index/2]);\r
1203 }\r
1204 }\r
1205 }\r
1206\r
1207 //\r
1208 // Convert value for NameValueVar2\r
1209 //\r
1210 if ((Value = StrStr (Configuration, PrivateData->NameValueName[2])) != NULL) {\r
1211 //\r
1212 // Skip "Name="\r
1213 //\r
1214 Value += StrLen (PrivateData->NameValueName[2]);\r
1215 Value++;\r
1216 //\r
1217 // Get Value String\r
1218 //\r
1219 StrPtr = StrStr (Value, L"&");\r
1220 if (StrPtr == NULL) {\r
1221 StrPtr = Value + StrLen (Value);\r
1222 }\r
1223 //\r
1224 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"\r
1225 //\r
1226 StrBuffer = (CHAR16 *) PrivateData->Configuration.NameValueVar2;\r
1227 ZeroMem (TemStr, sizeof (TemStr));\r
1228 while (Value < StrPtr) {\r
1229 StrnCpyS (TemStr, sizeof (TemStr) / sizeof (CHAR16), Value, 4);\r
1230 *(StrBuffer++) = (CHAR16) StrHexToUint64 (TemStr);\r
1231 Value += 4;\r
1232 }\r
1233 *StrBuffer = L'\0';\r
1234 }\r
1235\r
1236 //\r
1237 // Store Buffer Storage back to EFI variable\r
1238 //\r
1239 Status = gRT->SetVariable(\r
1240 VariableName,\r
1241 &gDriverSampleFormSetGuid,\r
1242 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
1243 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
1244 &PrivateData->Configuration\r
1245 );\r
1246\r
1247 return Status;\r
1248 }\r
1249\r
1250 //\r
1251 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
1252 //\r
1253 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
1254 Status = HiiConfigRouting->ConfigToBlock (\r
1255 HiiConfigRouting,\r
1256 Configuration,\r
1257 (UINT8 *) &PrivateData->Configuration,\r
1258 &BufferSize,\r
1259 Progress\r
1260 );\r
1261 if (EFI_ERROR (Status)) {\r
1262 return Status;\r
1263 }\r
1264\r
1265 //\r
1266 // Store Buffer Storage back to EFI variable\r
1267 //\r
1268 Status = gRT->SetVariable(\r
1269 VariableName,\r
1270 &gDriverSampleFormSetGuid,\r
1271 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
1272 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
1273 &PrivateData->Configuration\r
1274 );\r
1275\r
1276 return Status;\r
1277}\r
1278\r
1279\r
1280/**\r
1281 This function processes the results of changes in configuration.\r
1282\r
1283 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
1284 @param Action Specifies the type of action taken by the browser.\r
1285 @param QuestionId A unique value which is sent to the original\r
1286 exporting driver so that it can identify the type\r
1287 of data to expect.\r
1288 @param Type The type of value for the question.\r
1289 @param Value A pointer to the data being sent to the original\r
1290 exporting driver.\r
1291 @param ActionRequest On return, points to the action requested by the\r
1292 callback function.\r
1293\r
1294 @retval EFI_SUCCESS The callback successfully handled the action.\r
1295 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
1296 variable and its data.\r
1297 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
1298 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
1299 callback.\r
1300\r
1301**/\r
1302EFI_STATUS\r
1303EFIAPI\r
1304DriverCallback (\r
1305 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
1306 IN EFI_BROWSER_ACTION Action,\r
1307 IN EFI_QUESTION_ID QuestionId,\r
1308 IN UINT8 Type,\r
1309 IN EFI_IFR_TYPE_VALUE *Value,\r
1310 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
1311 )\r
1312{\r
1313 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;\r
1314 EFI_STATUS Status;\r
1315 VOID *StartOpCodeHandle;\r
1316 VOID *OptionsOpCodeHandle;\r
1317 EFI_IFR_GUID_LABEL *StartLabel;\r
1318 VOID *EndOpCodeHandle;\r
1319 EFI_IFR_GUID_LABEL *EndLabel;\r
1320 EFI_INPUT_KEY Key;\r
1321 DRIVER_SAMPLE_CONFIGURATION *Configuration;\r
1322 MY_EFI_VARSTORE_DATA *EfiData;\r
1323 EFI_FORM_ID FormId;\r
1324 EFI_STRING Progress;\r
1325 EFI_STRING Results;\r
1326 UINT32 ProgressErr;\r
1327 CHAR16 *TmpStr;\r
1328 UINTN Index;\r
1329 UINT64 BufferValue;\r
1330\r
1331 if (((Value == NULL) && (Action != EFI_BROWSER_ACTION_FORM_OPEN) && (Action != EFI_BROWSER_ACTION_FORM_CLOSE))||\r
1332 (ActionRequest == NULL)) {\r
1333 return EFI_INVALID_PARAMETER;\r
1334 }\r
1335\r
1336\r
1337 FormId = 0;\r
1338 ProgressErr = 0;\r
1339 Status = EFI_SUCCESS;\r
1340 BufferValue = 3;\r
1341 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
1342\r
1343 switch (Action) {\r
1344 case EFI_BROWSER_ACTION_FORM_OPEN:\r
1345 {\r
1346 if (QuestionId == 0x1234) {\r
1347 //\r
1348 // Sample CallBack for UEFI FORM_OPEN action:\r
1349 // Add Save action into Form 3 when Form 1 is opened.\r
1350 // This will be done only in FORM_OPEN CallBack of question with ID 0x1234 from Form 1.\r
1351 //\r
1352 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
1353\r
1354 //\r
1355 // Initialize the container for dynamic opcodes\r
1356 //\r
1357 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1358 ASSERT (StartOpCodeHandle != NULL);\r
1359\r
1360 //\r
1361 // Create Hii Extend Label OpCode as the start opcode\r
1362 //\r
1363 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1364 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1365 StartLabel->Number = LABEL_UPDATE2;\r
1366\r
1367 HiiCreateActionOpCode (\r
1368 StartOpCodeHandle, // Container for dynamic created opcodes\r
1369 0x1238, // Question ID\r
1370 STRING_TOKEN(STR_SAVE_TEXT), // Prompt text\r
1371 STRING_TOKEN(STR_SAVE_TEXT), // Help text\r
1372 EFI_IFR_FLAG_CALLBACK, // Question flag\r
1373 0 // Action String ID\r
1374 );\r
1375\r
1376 HiiUpdateForm (\r
1377 PrivateData->HiiHandle[0], // HII handle\r
1378 &gDriverSampleFormSetGuid, // Formset GUID\r
1379 0x3, // Form ID\r
1380 StartOpCodeHandle, // Label for where to insert opcodes\r
1381 NULL // Insert data\r
1382 );\r
1383\r
1384 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
1385 }\r
1386\r
1387 if (QuestionId == 0x1247) {\r
1388 Status = InternalStartMonitor ();\r
1389 ASSERT_EFI_ERROR (Status);\r
1390 }\r
1391 }\r
1392 break;\r
1393\r
1394 case EFI_BROWSER_ACTION_FORM_CLOSE:\r
1395 {\r
1396 if (QuestionId == 0x5678) {\r
1397 //\r
1398 // Sample CallBack for UEFI FORM_CLOSE action:\r
1399 // Show up a pop-up to specify Form 3 will be closed when exit Form 3.\r
1400 //\r
1401 do {\r
1402 CreatePopUp (\r
1403 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1404 &Key,\r
1405 L"",\r
1406 L"You are going to leave third Form!",\r
1407 L"Press ESC or ENTER to continue ...",\r
1408 L"",\r
1409 NULL\r
1410 );\r
1411 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
1412 }\r
1413\r
1414 if (QuestionId == 0x1247) {\r
1415 Status = InternalStopMonitor ();\r
1416 ASSERT_EFI_ERROR (Status);\r
1417 }\r
1418 }\r
1419 break;\r
1420 \r
1421 case EFI_BROWSER_ACTION_RETRIEVE:\r
1422 {\r
1423 switch (QuestionId ) {\r
1424 case 0x1248:\r
1425 if (Type != EFI_IFR_TYPE_REF) {\r
1426 return EFI_INVALID_PARAMETER;\r
1427 }\r
1428 Value->ref.FormId = 0x3;\r
1429 break;\r
1430\r
1431 case 0x5678:\r
1432 case 0x1247:\r
1433 //\r
1434 // We will reach here once the Question is refreshed\r
1435 //\r
1436\r
1437 //\r
1438 // Initialize the container for dynamic opcodes\r
1439 //\r
1440 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1441 ASSERT (StartOpCodeHandle != NULL);\r
1442\r
1443 //\r
1444 // Create Hii Extend Label OpCode as the start opcode\r
1445 //\r
1446 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1447 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1448 if (QuestionId == 0x5678) {\r
1449 StartLabel->Number = LABEL_UPDATE2;\r
1450 FormId = 0x03;\r
1451 PrivateData->Configuration.DynamicRefresh++;\r
1452 } else if (QuestionId == 0x1247 ) {\r
1453 StartLabel->Number = LABEL_UPDATE3;\r
1454 FormId = 0x06;\r
1455 PrivateData->Configuration.RefreshGuidCount++;\r
1456 }\r
1457\r
1458 HiiCreateActionOpCode (\r
1459 StartOpCodeHandle, // Container for dynamic created opcodes\r
1460 0x1237, // Question ID\r
1461 STRING_TOKEN(STR_EXIT_TEXT), // Prompt text\r
1462 STRING_TOKEN(STR_EXIT_TEXT), // Help text\r
1463 EFI_IFR_FLAG_CALLBACK, // Question flag\r
1464 0 // Action String ID\r
1465 );\r
1466 \r
1467 HiiUpdateForm (\r
1468 PrivateData->HiiHandle[0], // HII handle\r
1469 &gDriverSampleFormSetGuid, // Formset GUID\r
1470 FormId, // Form ID\r
1471 StartOpCodeHandle, // Label for where to insert opcodes\r
1472 NULL // Insert data\r
1473 );\r
1474\r
1475 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
1476\r
1477 //\r
1478 // Refresh the Question value\r
1479 //\r
1480 Status = gRT->SetVariable(\r
1481 VariableName,\r
1482 &gDriverSampleFormSetGuid,\r
1483 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
1484 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
1485 &PrivateData->Configuration\r
1486 );\r
1487\r
1488 if (QuestionId == 0x5678) {\r
1489 //\r
1490 // Update uncommitted data of Browser\r
1491 //\r
1492 EfiData = AllocateZeroPool (sizeof (MY_EFI_VARSTORE_DATA));\r
1493 ASSERT (EfiData != NULL);\r
1494 if (HiiGetBrowserData (&gDriverSampleFormSetGuid, MyEfiVar, sizeof (MY_EFI_VARSTORE_DATA), (UINT8 *) EfiData)) {\r
1495 EfiData->Field8 = 111;\r
1496 HiiSetBrowserData (\r
1497 &gDriverSampleFormSetGuid,\r
1498 MyEfiVar,\r
1499 sizeof (MY_EFI_VARSTORE_DATA),\r
1500 (UINT8 *) EfiData,\r
1501 NULL\r
1502 );\r
1503 }\r
1504 FreePool (EfiData);\r
1505 }\r
1506 break;\r
1507 }\r
1508 }\r
1509 break;\r
1510\r
1511 case EFI_BROWSER_ACTION_DEFAULT_STANDARD:\r
1512 {\r
1513 switch (QuestionId) {\r
1514 case 0x1240:\r
1515 Value->u8 = DEFAULT_CLASS_STANDARD_VALUE;\r
1516 break;\r
1517\r
1518 case 0x1252:\r
1519 for (Index = 0; Index < 3; Index ++) {\r
1520 SetArrayData (Value, EFI_IFR_TYPE_NUM_SIZE_8, Index, BufferValue--);\r
1521 }\r
1522 break;\r
1523\r
1524 default:\r
1525 Status = EFI_UNSUPPORTED;\r
1526 break;\r
1527 }\r
1528 }\r
1529 break;\r
1530\r
1531 case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING:\r
1532 {\r
1533 switch (QuestionId) {\r
1534 case 0x1240:\r
1535 Value->u8 = DEFAULT_CLASS_MANUFACTURING_VALUE;\r
1536 break;\r
1537\r
1538 default:\r
1539 Status = EFI_UNSUPPORTED; \r
1540 break;\r
1541 }\r
1542 }\r
1543 break;\r
1544\r
1545 case EFI_BROWSER_ACTION_CHANGING:\r
1546 {\r
1547 switch (QuestionId) {\r
1548 case 0x1249:\r
1549 {\r
1550 if (Type != EFI_IFR_TYPE_REF) {\r
1551 return EFI_INVALID_PARAMETER;\r
1552 }\r
1553\r
1554 Value->ref.FormId = 0x1234;\r
1555 }\r
1556 break;\r
1557 case 0x1234:\r
1558 //\r
1559 // Initialize the container for dynamic opcodes\r
1560 //\r
1561 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1562 ASSERT (StartOpCodeHandle != NULL);\r
1563\r
1564 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1565 ASSERT (EndOpCodeHandle != NULL);\r
1566\r
1567 //\r
1568 // Create Hii Extend Label OpCode as the start opcode\r
1569 //\r
1570 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1571 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1572 StartLabel->Number = LABEL_UPDATE1;\r
1573\r
1574 //\r
1575 // Create Hii Extend Label OpCode as the end opcode\r
1576 //\r
1577 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1578 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1579 EndLabel->Number = LABEL_END;\r
1580\r
1581 HiiCreateActionOpCode (\r
1582 StartOpCodeHandle, // Container for dynamic created opcodes\r
1583 0x1237, // Question ID\r
1584 STRING_TOKEN(STR_EXIT_TEXT), // Prompt text\r
1585 STRING_TOKEN(STR_EXIT_TEXT), // Help text\r
1586 EFI_IFR_FLAG_CALLBACK, // Question flag\r
1587 0 // Action String ID\r
1588 );\r
1589\r
1590 //\r
1591 // Create Option OpCode\r
1592 //\r
1593 OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1594 ASSERT (OptionsOpCodeHandle != NULL);\r
1595\r
1596 HiiCreateOneOfOptionOpCode (\r
1597 OptionsOpCodeHandle,\r
1598 STRING_TOKEN (STR_BOOT_OPTION1),\r
1599 0,\r
1600 EFI_IFR_NUMERIC_SIZE_1,\r
1601 1\r
1602 );\r
1603\r
1604 HiiCreateOneOfOptionOpCode (\r
1605 OptionsOpCodeHandle,\r
1606 STRING_TOKEN (STR_BOOT_OPTION2),\r
1607 0,\r
1608 EFI_IFR_NUMERIC_SIZE_1,\r
1609 2\r
1610 );\r
1611\r
1612 //\r
1613 // Prepare initial value for the dynamic created oneof Question\r
1614 //\r
1615 PrivateData->Configuration.DynamicOneof = 2;\r
1616 Status = gRT->SetVariable(\r
1617 VariableName,\r
1618 &gDriverSampleFormSetGuid,\r
1619 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
1620 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
1621 &PrivateData->Configuration\r
1622 );\r
1623\r
1624 //\r
1625 // Set initial vlaue of dynamic created oneof Question in Form Browser\r
1626 //\r
1627 Configuration = AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION));\r
1628 ASSERT (Configuration != NULL);\r
1629 if (HiiGetBrowserData (&gDriverSampleFormSetGuid, VariableName, sizeof (DRIVER_SAMPLE_CONFIGURATION), (UINT8 *) Configuration)) {\r
1630 Configuration->DynamicOneof = 2;\r
1631\r
1632 //\r
1633 // Update uncommitted data of Browser\r
1634 //\r
1635 HiiSetBrowserData (\r
1636 &gDriverSampleFormSetGuid,\r
1637 VariableName,\r
1638 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
1639 (UINT8 *) Configuration,\r
1640 NULL\r
1641 );\r
1642 }\r
1643 FreePool (Configuration);\r
1644\r
1645 HiiCreateOneOfOpCode (\r
1646 StartOpCodeHandle, // Container for dynamic created opcodes\r
1647 0x8001, // Question ID (or call it "key")\r
1648 CONFIGURATION_VARSTORE_ID, // VarStore ID\r
1649 (UINT16) DYNAMIC_ONE_OF_VAR_OFFSET, // Offset in Buffer Storage\r
1650 STRING_TOKEN (STR_ONE_OF_PROMPT), // Question prompt text\r
1651 STRING_TOKEN (STR_ONE_OF_HELP), // Question help text\r
1652 EFI_IFR_FLAG_CALLBACK, // Question flag\r
1653 EFI_IFR_NUMERIC_SIZE_1, // Data type of Question Value\r
1654 OptionsOpCodeHandle, // Option Opcode list\r
1655 NULL // Default Opcode is NULl\r
1656 );\r
1657\r
1658 HiiCreateOrderedListOpCode (\r
1659 StartOpCodeHandle, // Container for dynamic created opcodes\r
1660 0x8002, // Question ID\r
1661 CONFIGURATION_VARSTORE_ID, // VarStore ID\r
1662 (UINT16) DYNAMIC_ORDERED_LIST_VAR_OFFSET, // Offset in Buffer Storage\r
1663 STRING_TOKEN (STR_BOOT_OPTIONS), // Question prompt text\r
1664 STRING_TOKEN (STR_BOOT_OPTIONS), // Question help text\r
1665 EFI_IFR_FLAG_RESET_REQUIRED, // Question flag\r
1666 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET\r
1667 EFI_IFR_NUMERIC_SIZE_1, // Data type of Question value\r
1668 5, // Maximum container\r
1669 OptionsOpCodeHandle, // Option Opcode list\r
1670 NULL // Default Opcode is NULl\r
1671 );\r
1672\r
1673 HiiCreateTextOpCode (\r
1674 StartOpCodeHandle,\r
1675 STRING_TOKEN(STR_TEXT_SAMPLE_HELP),\r
1676 STRING_TOKEN(STR_TEXT_SAMPLE_HELP),\r
1677 STRING_TOKEN(STR_TEXT_SAMPLE_STRING)\r
1678 );\r
1679\r
1680 HiiCreateDateOpCode (\r
1681 StartOpCodeHandle,\r
1682 0x8004,\r
1683 0x0,\r
1684 0x0,\r
1685 STRING_TOKEN(STR_DATE_SAMPLE_HELP),\r
1686 STRING_TOKEN(STR_DATE_SAMPLE_HELP),\r
1687 0,\r
1688 QF_DATE_STORAGE_TIME,\r
1689 NULL\r
1690 );\r
1691\r
1692 HiiCreateTimeOpCode (\r
1693 StartOpCodeHandle,\r
1694 0x8005,\r
1695 0x0,\r
1696 0x0,\r
1697 STRING_TOKEN(STR_TIME_SAMPLE_HELP),\r
1698 STRING_TOKEN(STR_TIME_SAMPLE_HELP),\r
1699 0,\r
1700 QF_TIME_STORAGE_TIME,\r
1701 NULL\r
1702 );\r
1703\r
1704 HiiCreateGotoOpCode (\r
1705 StartOpCodeHandle, // Container for dynamic created opcodes\r
1706 1, // Target Form ID\r
1707 STRING_TOKEN (STR_GOTO_FORM1), // Prompt text\r
1708 STRING_TOKEN (STR_GOTO_HELP), // Help text\r
1709 0, // Question flag\r
1710 0x8003 // Question ID\r
1711 );\r
1712\r
1713 HiiUpdateForm (\r
1714 PrivateData->HiiHandle[0], // HII handle\r
1715 &gDriverSampleFormSetGuid, // Formset GUID\r
1716 0x1234, // Form ID\r
1717 StartOpCodeHandle, // Label for where to insert opcodes\r
1718 EndOpCodeHandle // Replace data\r
1719 );\r
1720\r
1721 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
1722 HiiFreeOpCodeHandle (OptionsOpCodeHandle);\r
1723 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
1724 break;\r
1725\r
1726 case 0x2000:\r
1727 //\r
1728 // Only used to update the state.\r
1729 //\r
1730 if ((Type == EFI_IFR_TYPE_STRING) && (Value->string == 0) && \r
1731 (PrivateData->PasswordState == BROWSER_STATE_SET_PASSWORD)) {\r
1732 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;\r
1733 return EFI_INVALID_PARAMETER;\r
1734 }\r
1735\r
1736 //\r
1737 // When try to set a new password, user will be chanlleged with old password.\r
1738 // The Callback is responsible for validating old password input by user,\r
1739 // If Callback return EFI_SUCCESS, it indicates validation pass.\r
1740 //\r
1741 switch (PrivateData->PasswordState) {\r
1742 case BROWSER_STATE_VALIDATE_PASSWORD:\r
1743 Status = ValidatePassword (PrivateData, Value->string);\r
1744 if (Status == EFI_SUCCESS) {\r
1745 PrivateData->PasswordState = BROWSER_STATE_SET_PASSWORD;\r
1746 }\r
1747 break;\r
1748\r
1749 case BROWSER_STATE_SET_PASSWORD:\r
1750 Status = SetPassword (PrivateData, Value->string);\r
1751 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;\r
1752 break;\r
1753\r
1754 default:\r
1755 break;\r
1756 }\r
1757\r
1758 break;\r
1759\r
1760 default:\r
1761 break;\r
1762 }\r
1763 }\r
1764 break;\r
1765\r
1766 case EFI_BROWSER_ACTION_CHANGED:\r
1767 switch (QuestionId) {\r
1768 case 0x1237:\r
1769 //\r
1770 // User press "Exit now", request Browser to exit\r
1771 //\r
1772 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
1773 break;\r
1774 \r
1775 case 0x1238:\r
1776 //\r
1777 // User press "Save now", request Browser to save the uncommitted data.\r
1778 //\r
1779 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
1780 break;\r
1781 \r
1782 case 0x1241:\r
1783 case 0x1246:\r
1784 //\r
1785 // User press "Submit current form and Exit now", request Browser to submit current form and exit\r
1786 //\r
1787 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
1788 break;\r
1789 \r
1790 case 0x1242:\r
1791 //\r
1792 // User press "Discard current form now", request Browser to discard the uncommitted data.\r
1793 //\r
1794 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD;\r
1795 break;\r
1796 \r
1797 case 0x1243:\r
1798 //\r
1799 // User press "Submit current form now", request Browser to save the uncommitted data.\r
1800 //\r
1801 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;\r
1802 break;\r
1803 \r
1804 case 0x1244:\r
1805 case 0x1245:\r
1806 //\r
1807 // User press "Discard current form and Exit now", request Browser to discard the uncommitted data and exit.\r
1808 //\r
1809 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
1810 break;\r
1811\r
1812 case 0x1231:\r
1813 //\r
1814 // 1. Check to see whether system support keyword.\r
1815 //\r
1816 Status = PrivateData->HiiKeywordHandler->GetData (PrivateData->HiiKeywordHandler,\r
1817 L"NAMESPACE=x-UEFI-ns",\r
1818 L"KEYWORD=iSCSIBootEnable",\r
1819 &Progress,\r
1820 &ProgressErr,\r
1821 &Results\r
1822 );\r
1823 if (EFI_ERROR (Status)) {\r
1824 do {\r
1825 CreatePopUp (\r
1826 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1827 &Key,\r
1828 L"",\r
1829 L"This system not support this keyword!",\r
1830 L"Press ENTER to continue ...",\r
1831 L"",\r
1832 NULL\r
1833 );\r
1834 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1835\r
1836 Status = EFI_SUCCESS;\r
1837 break;\r
1838 }\r
1839\r
1840 //\r
1841 // 2. If system support this keyword, just try to change value.\r
1842 //\r
1843 \r
1844 //\r
1845 // Change value from '0' to '1' or from '1' to '0'\r
1846 //\r
1847 TmpStr = StrStr (Results, L"&VALUE=");\r
1848 ASSERT (TmpStr != NULL);\r
1849 TmpStr += StrLen (L"&VALUE=");\r
1850 TmpStr++;\r
1851 if (*TmpStr == L'0') {\r
1852 *TmpStr = L'1';\r
1853 } else {\r
1854 *TmpStr = L'0';\r
1855 }\r
1856\r
1857 //\r
1858 // 3. Call the keyword handler protocol to change the value.\r
1859 //\r
1860 Status = PrivateData->HiiKeywordHandler->SetData (PrivateData->HiiKeywordHandler,\r
1861 Results,\r
1862 &Progress,\r
1863 &ProgressErr\r
1864 );\r
1865 if (EFI_ERROR (Status)) {\r
1866 do {\r
1867 CreatePopUp (\r
1868 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1869 &Key,\r
1870 L"",\r
1871 L"Set keyword to the system failed!",\r
1872 L"Press ENTER to continue ...",\r
1873 L"",\r
1874 NULL\r
1875 );\r
1876 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1877\r
1878 Status = EFI_SUCCESS;\r
1879 break;\r
1880 }\r
1881 break;\r
1882\r
1883 default:\r
1884 break;\r
1885 }\r
1886 break;\r
1887\r
1888 case EFI_BROWSER_ACTION_SUBMITTED:\r
1889 {\r
1890 if (QuestionId == 0x1250) {\r
1891 //\r
1892 // Sample CallBack for EFI_BROWSER_ACTION_SUBMITTED action:\r
1893 // Show up a pop-up to show SUBMITTED callback has been triggered.\r
1894 //\r
1895 do {\r
1896 CreatePopUp (\r
1897 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1898 &Key,\r
1899 L"",\r
1900 L"EfiVarstore value has been submitted!",\r
1901 L"Press ESC or ENTER to continue ...",\r
1902 L"",\r
1903 NULL\r
1904 );\r
1905 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
1906 }\r
1907 }\r
1908 break;\r
1909\r
1910 default:\r
1911 Status = EFI_UNSUPPORTED;\r
1912 break;\r
1913 }\r
1914\r
1915 return Status;\r
1916}\r
1917\r
1918/**\r
1919 Main entry for this driver.\r
1920\r
1921 @param ImageHandle Image handle this driver.\r
1922 @param SystemTable Pointer to SystemTable.\r
1923\r
1924 @retval EFI_SUCESS This function always complete successfully.\r
1925\r
1926**/\r
1927EFI_STATUS\r
1928EFIAPI\r
1929DriverSampleInit (\r
1930 IN EFI_HANDLE ImageHandle,\r
1931 IN EFI_SYSTEM_TABLE *SystemTable\r
1932 )\r
1933{\r
1934 EFI_STATUS Status;\r
1935 EFI_HII_HANDLE HiiHandle[2];\r
1936 EFI_SCREEN_DESCRIPTOR Screen;\r
1937 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;\r
1938 EFI_HII_STRING_PROTOCOL *HiiString;\r
1939 EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;\r
1940 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
1941 EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *HiiKeywordHandler;\r
1942 CHAR16 *NewString;\r
1943 UINTN BufferSize;\r
1944 DRIVER_SAMPLE_CONFIGURATION *Configuration;\r
1945 BOOLEAN ActionFlag;\r
1946 EFI_STRING ConfigRequestHdr;\r
1947 EFI_STRING NameRequestHdr;\r
1948 MY_EFI_VARSTORE_DATA *VarStoreConfig;\r
1949 EFI_INPUT_KEY HotKey;\r
1950 EFI_FORM_BROWSER_EXTENSION_PROTOCOL *FormBrowserEx;\r
1951\r
1952 //\r
1953 // Initialize the local variables.\r
1954 //\r
1955 ConfigRequestHdr = NULL;\r
1956 NewString = NULL;\r
1957\r
1958 //\r
1959 // Initialize screen dimensions for SendForm().\r
1960 // Remove 3 characters from top and bottom\r
1961 //\r
1962 ZeroMem (&Screen, sizeof (EFI_SCREEN_DESCRIPTOR));\r
1963 gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &Screen.RightColumn, &Screen.BottomRow);\r
1964\r
1965 Screen.TopRow = 3;\r
1966 Screen.BottomRow = Screen.BottomRow - 3;\r
1967\r
1968 //\r
1969 // Initialize driver private data\r
1970 //\r
1971 mPrivateData = AllocateZeroPool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA));\r
1972 if (mPrivateData == NULL) {\r
1973 return EFI_OUT_OF_RESOURCES;\r
1974 }\r
1975\r
1976 mPrivateData->Signature = DRIVER_SAMPLE_PRIVATE_SIGNATURE;\r
1977\r
1978 mPrivateData->ConfigAccess.ExtractConfig = ExtractConfig;\r
1979 mPrivateData->ConfigAccess.RouteConfig = RouteConfig;\r
1980 mPrivateData->ConfigAccess.Callback = DriverCallback;\r
1981 mPrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;\r
1982\r
1983 //\r
1984 // Locate Hii Database protocol\r
1985 //\r
1986 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiDatabase);\r
1987 if (EFI_ERROR (Status)) {\r
1988 return Status;\r
1989 }\r
1990 mPrivateData->HiiDatabase = HiiDatabase;\r
1991\r
1992 //\r
1993 // Locate HiiString protocol\r
1994 //\r
1995 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);\r
1996 if (EFI_ERROR (Status)) {\r
1997 return Status;\r
1998 }\r
1999 mPrivateData->HiiString = HiiString;\r
2000\r
2001 //\r
2002 // Locate Formbrowser2 protocol\r
2003 //\r
2004 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2);\r
2005 if (EFI_ERROR (Status)) {\r
2006 return Status;\r
2007 }\r
2008 mPrivateData->FormBrowser2 = FormBrowser2;\r
2009\r
2010 //\r
2011 // Locate ConfigRouting protocol\r
2012 //\r
2013 Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &HiiConfigRouting);\r
2014 if (EFI_ERROR (Status)) {\r
2015 return Status;\r
2016 }\r
2017 mPrivateData->HiiConfigRouting = HiiConfigRouting;\r
2018\r
2019 //\r
2020 // Locate keyword handler protocol\r
2021 //\r
2022 Status = gBS->LocateProtocol (&gEfiConfigKeywordHandlerProtocolGuid, NULL, (VOID **) &HiiKeywordHandler);\r
2023 if (EFI_ERROR (Status)) {\r
2024 return Status;\r
2025 }\r
2026 mPrivateData->HiiKeywordHandler = HiiKeywordHandler;\r
2027\r
2028 Status = gBS->InstallMultipleProtocolInterfaces (\r
2029 &DriverHandle[0],\r
2030 &gEfiDevicePathProtocolGuid,\r
2031 &mHiiVendorDevicePath0,\r
2032 &gEfiHiiConfigAccessProtocolGuid,\r
2033 &mPrivateData->ConfigAccess,\r
2034 NULL\r
2035 );\r
2036 ASSERT_EFI_ERROR (Status);\r
2037\r
2038 mPrivateData->DriverHandle[0] = DriverHandle[0];\r
2039\r
2040 //\r
2041 // Publish our HII data\r
2042 //\r
2043 HiiHandle[0] = HiiAddPackages (\r
2044 &gDriverSampleFormSetGuid,\r
2045 DriverHandle[0],\r
2046 DriverSampleStrings,\r
2047 VfrBin,\r
2048 NULL\r
2049 );\r
2050 if (HiiHandle[0] == NULL) {\r
2051 return EFI_OUT_OF_RESOURCES;\r
2052 }\r
2053\r
2054 mPrivateData->HiiHandle[0] = HiiHandle[0];\r
2055\r
2056 //\r
2057 // Publish another Fromset\r
2058 //\r
2059 Status = gBS->InstallMultipleProtocolInterfaces (\r
2060 &DriverHandle[1],\r
2061 &gEfiDevicePathProtocolGuid,\r
2062 &mHiiVendorDevicePath1,\r
2063 &gEfiHiiConfigAccessProtocolGuid,\r
2064 &mPrivateData->ConfigAccess,\r
2065 NULL\r
2066 );\r
2067 ASSERT_EFI_ERROR (Status);\r
2068\r
2069 mPrivateData->DriverHandle[1] = DriverHandle[1];\r
2070\r
2071 HiiHandle[1] = HiiAddPackages (\r
2072 &gDriverSampleInventoryGuid,\r
2073 DriverHandle[1],\r
2074 DriverSampleStrings,\r
2075 InventoryBin,\r
2076 NULL\r
2077 );\r
2078 if (HiiHandle[1] == NULL) {\r
2079 DriverSampleUnload (ImageHandle);\r
2080 return EFI_OUT_OF_RESOURCES;\r
2081 }\r
2082\r
2083 mPrivateData->HiiHandle[1] = HiiHandle[1];\r
2084\r
2085 //\r
2086 // Update the device path string.\r
2087 //\r
2088 NewString = ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL*)&mHiiVendorDevicePath0, FALSE, FALSE);\r
2089 if (HiiSetString (HiiHandle[0], STRING_TOKEN (STR_DEVICE_PATH), NewString, NULL) == 0) {\r
2090 DriverSampleUnload (ImageHandle);\r
2091 return EFI_OUT_OF_RESOURCES;\r
2092 }\r
2093 if (NewString != NULL) {\r
2094 FreePool (NewString);\r
2095 }\r
2096\r
2097 //\r
2098 // Very simple example of how one would update a string that is already\r
2099 // in the HII database\r
2100 //\r
2101 NewString = L"700 Mhz";\r
2102\r
2103 if (HiiSetString (HiiHandle[0], STRING_TOKEN (STR_CPU_STRING2), NewString, NULL) == 0) {\r
2104 DriverSampleUnload (ImageHandle);\r
2105 return EFI_OUT_OF_RESOURCES;\r
2106 }\r
2107\r
2108 HiiSetString (HiiHandle[0], 0, NewString, NULL);\r
2109\r
2110 //\r
2111 // Initialize Name/Value name String ID\r
2112 //\r
2113 mPrivateData->NameStringId[0] = STR_NAME_VALUE_VAR_NAME0;\r
2114 mPrivateData->NameStringId[1] = STR_NAME_VALUE_VAR_NAME1;\r
2115 mPrivateData->NameStringId[2] = STR_NAME_VALUE_VAR_NAME2;\r
2116\r
2117 //\r
2118 // Initialize configuration data\r
2119 //\r
2120 Configuration = &mPrivateData->Configuration;\r
2121 ZeroMem (Configuration, sizeof (DRIVER_SAMPLE_CONFIGURATION));\r
2122\r
2123 //\r
2124 // Try to read NV config EFI variable first\r
2125 //\r
2126 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, DriverHandle[0]);\r
2127 ASSERT (ConfigRequestHdr != NULL);\r
2128\r
2129 NameRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, NULL, DriverHandle[0]);\r
2130 ASSERT (NameRequestHdr != NULL);\r
2131\r
2132 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
2133 Status = gRT->GetVariable (VariableName, &gDriverSampleFormSetGuid, NULL, &BufferSize, Configuration);\r
2134 if (EFI_ERROR (Status)) {\r
2135 //\r
2136 // Store zero data Buffer Storage to EFI variable\r
2137 //\r
2138 Status = gRT->SetVariable(\r
2139 VariableName,\r
2140 &gDriverSampleFormSetGuid,\r
2141 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
2142 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
2143 Configuration\r
2144 );\r
2145 if (EFI_ERROR (Status)) {\r
2146 DriverSampleUnload (ImageHandle);\r
2147 return Status;\r
2148 }\r
2149 //\r
2150 // EFI variable for NV config doesn't exit, we should build this variable\r
2151 // based on default values stored in IFR\r
2152 //\r
2153 ActionFlag = HiiSetToDefaults (NameRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);\r
2154 if (!ActionFlag) {\r
2155 DriverSampleUnload (ImageHandle);\r
2156 return EFI_INVALID_PARAMETER;\r
2157 }\r
2158\r
2159 ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);\r
2160 if (!ActionFlag) {\r
2161 DriverSampleUnload (ImageHandle);\r
2162 return EFI_INVALID_PARAMETER;\r
2163 }\r
2164 } else {\r
2165 //\r
2166 // EFI variable does exist and Validate Current Setting\r
2167 //\r
2168 ActionFlag = HiiValidateSettings (NameRequestHdr);\r
2169 if (!ActionFlag) {\r
2170 DriverSampleUnload (ImageHandle);\r
2171 return EFI_INVALID_PARAMETER;\r
2172 }\r
2173\r
2174 ActionFlag = HiiValidateSettings (ConfigRequestHdr);\r
2175 if (!ActionFlag) {\r
2176 DriverSampleUnload (ImageHandle);\r
2177 return EFI_INVALID_PARAMETER;\r
2178 }\r
2179 }\r
2180 FreePool (ConfigRequestHdr);\r
2181\r
2182 //\r
2183 // Initialize efi varstore configuration data\r
2184 //\r
2185 VarStoreConfig = &mPrivateData->VarStoreConfig;\r
2186 ZeroMem (VarStoreConfig, sizeof (MY_EFI_VARSTORE_DATA));\r
2187\r
2188 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, MyEfiVar, DriverHandle[0]);\r
2189 ASSERT (ConfigRequestHdr != NULL);\r
2190\r
2191 BufferSize = sizeof (MY_EFI_VARSTORE_DATA);\r
2192 Status = gRT->GetVariable (MyEfiVar, &gDriverSampleFormSetGuid, NULL, &BufferSize, VarStoreConfig);\r
2193 if (EFI_ERROR (Status)) {\r
2194 //\r
2195 // Store zero data to EFI variable Storage.\r
2196 //\r
2197 Status = gRT->SetVariable(\r
2198 MyEfiVar,\r
2199 &gDriverSampleFormSetGuid,\r
2200 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
2201 sizeof (MY_EFI_VARSTORE_DATA),\r
2202 VarStoreConfig\r
2203 );\r
2204 if (EFI_ERROR (Status)) {\r
2205 DriverSampleUnload (ImageHandle);\r
2206 return Status;\r
2207 }\r
2208 //\r
2209 // EFI variable for NV config doesn't exit, we should build this variable\r
2210 // based on default values stored in IFR\r
2211 //\r
2212 ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);\r
2213 if (!ActionFlag) {\r
2214 DriverSampleUnload (ImageHandle);\r
2215 return EFI_INVALID_PARAMETER;\r
2216 }\r
2217 } else {\r
2218 //\r
2219 // EFI variable does exist and Validate Current Setting\r
2220 //\r
2221 ActionFlag = HiiValidateSettings (ConfigRequestHdr);\r
2222 if (!ActionFlag) {\r
2223 DriverSampleUnload (ImageHandle);\r
2224 return EFI_INVALID_PARAMETER;\r
2225 }\r
2226 }\r
2227 FreePool (ConfigRequestHdr);\r
2228\r
2229 Status = gBS->CreateEventEx (\r
2230 EVT_NOTIFY_SIGNAL, \r
2231 TPL_NOTIFY,\r
2232 DriverSampleInternalEmptyFunction,\r
2233 NULL,\r
2234 &gEfiIfrRefreshIdOpGuid,\r
2235 &mEvent\r
2236 );\r
2237 ASSERT_EFI_ERROR (Status);\r
2238\r
2239 //\r
2240 // Example of how to use BrowserEx protocol to register HotKey.\r
2241 // \r
2242 Status = gBS->LocateProtocol (&gEfiFormBrowserExProtocolGuid, NULL, (VOID **) &FormBrowserEx);\r
2243 if (!EFI_ERROR (Status)) {\r
2244 //\r
2245 // First unregister the default hot key F9 and F10.\r
2246 //\r
2247 HotKey.UnicodeChar = CHAR_NULL;\r
2248 HotKey.ScanCode = SCAN_F9;\r
2249 FormBrowserEx->RegisterHotKey (&HotKey, 0, 0, NULL);\r
2250 HotKey.ScanCode = SCAN_F10;\r
2251 FormBrowserEx->RegisterHotKey (&HotKey, 0, 0, NULL);\r
2252 \r
2253 //\r
2254 // Register the default HotKey F9 and F10 again.\r
2255 //\r
2256 HotKey.ScanCode = SCAN_F10;\r
2257 NewString = HiiGetString (mPrivateData->HiiHandle[0], STRING_TOKEN (FUNCTION_TEN_STRING), NULL);\r
2258 ASSERT (NewString != NULL);\r
2259 FormBrowserEx->RegisterHotKey (&HotKey, BROWSER_ACTION_SUBMIT, 0, NewString);\r
2260 HotKey.ScanCode = SCAN_F9;\r
2261 NewString = HiiGetString (mPrivateData->HiiHandle[0], STRING_TOKEN (FUNCTION_NINE_STRING), NULL);\r
2262 ASSERT (NewString != NULL);\r
2263 FormBrowserEx->RegisterHotKey (&HotKey, BROWSER_ACTION_DEFAULT, EFI_HII_DEFAULT_CLASS_STANDARD, NewString);\r
2264 }\r
2265\r
2266 //\r
2267 // In default, this driver is built into Flash device image,\r
2268 // the following code doesn't run.\r
2269 //\r
2270\r
2271 //\r
2272 // Example of how to display only the item we sent to HII\r
2273 // When this driver is not built into Flash device image,\r
2274 // it need to call SendForm to show front page by itself.\r
2275 //\r
2276 if (DISPLAY_ONLY_MY_ITEM <= 1) {\r
2277 //\r
2278 // Have the browser pull out our copy of the data, and only display our data\r
2279 //\r
2280 Status = FormBrowser2->SendForm (\r
2281 FormBrowser2,\r
2282 &(HiiHandle[DISPLAY_ONLY_MY_ITEM]),\r
2283 1,\r
2284 NULL,\r
2285 0,\r
2286 NULL,\r
2287 NULL\r
2288 );\r
2289\r
2290 HiiRemovePackages (HiiHandle[0]);\r
2291\r
2292 HiiRemovePackages (HiiHandle[1]);\r
2293 }\r
2294\r
2295 return EFI_SUCCESS;\r
2296}\r
2297\r
2298/**\r
2299 Unloads the application and its installed protocol.\r
2300\r
2301 @param[in] ImageHandle Handle that identifies the image to be unloaded.\r
2302\r
2303 @retval EFI_SUCCESS The image has been unloaded.\r
2304**/\r
2305EFI_STATUS\r
2306EFIAPI\r
2307DriverSampleUnload (\r
2308 IN EFI_HANDLE ImageHandle\r
2309 )\r
2310{\r
2311 UINTN Index;\r
2312\r
2313 ASSERT (mPrivateData != NULL);\r
2314\r
2315 if (DriverHandle[0] != NULL) {\r
2316 gBS->UninstallMultipleProtocolInterfaces (\r
2317 DriverHandle[0],\r
2318 &gEfiDevicePathProtocolGuid,\r
2319 &mHiiVendorDevicePath0,\r
2320 &gEfiHiiConfigAccessProtocolGuid,\r
2321 &mPrivateData->ConfigAccess,\r
2322 NULL\r
2323 );\r
2324 DriverHandle[0] = NULL;\r
2325 }\r
2326\r
2327 if (DriverHandle[1] != NULL) {\r
2328 gBS->UninstallMultipleProtocolInterfaces (\r
2329 DriverHandle[1],\r
2330 &gEfiDevicePathProtocolGuid,\r
2331 &mHiiVendorDevicePath1,\r
2332 &gEfiHiiConfigAccessProtocolGuid,\r
2333 &mPrivateData->ConfigAccess,\r
2334 NULL\r
2335 );\r
2336 DriverHandle[1] = NULL;\r
2337 }\r
2338\r
2339 if (mPrivateData->HiiHandle[0] != NULL) {\r
2340 HiiRemovePackages (mPrivateData->HiiHandle[0]);\r
2341 }\r
2342\r
2343 if (mPrivateData->HiiHandle[1] != NULL) {\r
2344 HiiRemovePackages (mPrivateData->HiiHandle[1]);\r
2345 }\r
2346\r
2347 for (Index = 0; Index < NAME_VALUE_NAME_NUMBER; Index++) {\r
2348 if (mPrivateData->NameValueName[Index] != NULL) {\r
2349 FreePool (mPrivateData->NameValueName[Index]);\r
2350 }\r
2351 }\r
2352 FreePool (mPrivateData);\r
2353 mPrivateData = NULL;\r
2354\r
2355 gBS->CloseEvent (mEvent);\r
2356\r
2357 return EFI_SUCCESS;\r
2358}\r