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