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