]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c
Update all the code to consume the ConvertDevicePathToText, ConvertDevicePathNodeToTe...
[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 - 2013, 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 UINTN Length;
666 UINT8 *TmpBuffer;
667 UINTN Offset;
668 UINTN Width;
669 UINTN BlockSize;
670 UINTN ValueOffset;
671 UINTN ValueWidth;
672 EFI_STATUS Status;
673
674 StringPtr = *RequestResult;
675 StringPtr = StrStr (StringPtr, L"OFFSET");
676 BlockSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
677 ValueOffset = OFFSET_OF (DRIVER_SAMPLE_CONFIGURATION, GetDefaultValueFromAccess);
678 ValueWidth = sizeof (((DRIVER_SAMPLE_CONFIGURATION *)0)->GetDefaultValueFromAccess);
679
680 if (StringPtr == NULL) {
681 return;
682 }
683
684 while (*StringPtr != 0 && StrnCmp (StringPtr, L"OFFSET=", StrLen (L"OFFSET=")) == 0) {
685 StringPtr += StrLen (L"OFFSET=");
686 //
687 // Get Offset
688 //
689 Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
690 if (EFI_ERROR (Status)) {
691 return;
692 }
693 Offset = 0;
694 CopyMem (
695 &Offset,
696 TmpBuffer,
697 (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)
698 );
699 FreePool (TmpBuffer);
700
701 StringPtr += Length;
702 if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {
703 return;
704 }
705 StringPtr += StrLen (L"&WIDTH=");
706
707 //
708 // Get Width
709 //
710 Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
711 if (EFI_ERROR (Status)) {
712 return;
713 }
714 Width = 0;
715 CopyMem (
716 &Width,
717 TmpBuffer,
718 (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)
719 );
720 FreePool (TmpBuffer);
721
722 StringPtr += Length;
723 if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) != 0) {
724 return;
725 }
726 StringPtr += StrLen (L"&VALUE=");
727
728 //
729 // Get Value
730 //
731 Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
732 if (EFI_ERROR (Status)) {
733 return;
734 }
735 StringPtr += Length;
736
737 //
738 // Calculate Value and convert it to hex string.
739 //
740 if (Offset + Width > BlockSize) {
741 return;
742 }
743
744 if (Offset <= ValueOffset && Offset + Width >= ValueOffset + ValueWidth) {
745 *RequestResult = CreateAltCfgString(*RequestResult, ConfigRequestHdr, ValueOffset, ValueWidth);
746 return;
747 }
748 }
749 }
750
751 /**
752 This function allows a caller to extract the current configuration for one
753 or more named elements from the target driver.
754
755 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
756 @param Request A null-terminated Unicode string in
757 <ConfigRequest> format.
758 @param Progress On return, points to a character in the Request
759 string. Points to the string's null terminator if
760 request was successful. Points to the most recent
761 '&' before the first failing name/value pair (or
762 the beginning of the string if the failure is in
763 the first name/value pair) if the request was not
764 successful.
765 @param Results A null-terminated Unicode string in
766 <ConfigAltResp> format which has all values filled
767 in for the names in the Request string. String to
768 be allocated by the called function.
769
770 @retval EFI_SUCCESS The Results is filled with the requested values.
771 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
772 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
773 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
774 driver.
775
776 **/
777 EFI_STATUS
778 EFIAPI
779 ExtractConfig (
780 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
781 IN CONST EFI_STRING Request,
782 OUT EFI_STRING *Progress,
783 OUT EFI_STRING *Results
784 )
785 {
786 EFI_STATUS Status;
787 UINTN BufferSize;
788 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;
789 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
790 EFI_STRING ConfigRequest;
791 EFI_STRING ConfigRequestHdr;
792 UINTN Size;
793 EFI_STRING Value;
794 UINTN ValueStrLen;
795 CHAR16 BackupChar;
796 CHAR16 *StrPointer;
797 BOOLEAN AllocatedRequest;
798
799 if (Progress == NULL || Results == NULL) {
800 return EFI_INVALID_PARAMETER;
801 }
802 //
803 // Initialize the local variables.
804 //
805 ConfigRequestHdr = NULL;
806 ConfigRequest = NULL;
807 Size = 0;
808 *Progress = Request;
809 AllocatedRequest = FALSE;
810
811 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);
812 HiiConfigRouting = PrivateData->HiiConfigRouting;
813
814 //
815 // Get Buffer Storage data from EFI variable.
816 // Try to get the current setting from variable.
817 //
818 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
819 Status = gRT->GetVariable (
820 VariableName,
821 &gDriverSampleFormSetGuid,
822 NULL,
823 &BufferSize,
824 &PrivateData->Configuration
825 );
826 if (EFI_ERROR (Status)) {
827 return EFI_NOT_FOUND;
828 }
829
830 if (Request == NULL) {
831 //
832 // Request is set to NULL, construct full request string.
833 //
834
835 //
836 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
837 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
838 //
839 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, PrivateData->DriverHandle[0]);
840 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
841 ConfigRequest = AllocateZeroPool (Size);
842 ASSERT (ConfigRequest != NULL);
843 AllocatedRequest = TRUE;
844 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
845 FreePool (ConfigRequestHdr);
846 ConfigRequestHdr = NULL;
847 } else {
848 //
849 // Check routing data in <ConfigHdr>.
850 // Note: if only one Storage is used, then this checking could be skipped.
851 //
852 if (!HiiIsConfigHdrMatch (Request, &gDriverSampleFormSetGuid, NULL)) {
853 return EFI_NOT_FOUND;
854 }
855 //
856 // Check whether request for EFI Varstore. EFI varstore get data
857 // through hii database, not support in this path.
858 //
859 if (HiiIsConfigHdrMatch(Request, &gDriverSampleFormSetGuid, MyEfiVar)) {
860 return EFI_UNSUPPORTED;
861 }
862 //
863 // Set Request to the unified request string.
864 //
865 ConfigRequest = Request;
866 //
867 // Check whether Request includes Request Element.
868 //
869 if (StrStr (Request, L"OFFSET") == NULL) {
870 //
871 // Check Request Element does exist in Reques String
872 //
873 StrPointer = StrStr (Request, L"PATH");
874 if (StrPointer == NULL) {
875 return EFI_INVALID_PARAMETER;
876 }
877 if (StrStr (StrPointer, L"&") == NULL) {
878 Size = (StrLen (Request) + 32 + 1) * sizeof (CHAR16);
879 ConfigRequest = AllocateZeroPool (Size);
880 ASSERT (ConfigRequest != NULL);
881 AllocatedRequest = TRUE;
882 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", Request, (UINT64)BufferSize);
883 }
884 }
885 }
886
887 //
888 // Check if requesting Name/Value storage
889 //
890 if (StrStr (ConfigRequest, L"OFFSET") == NULL) {
891 //
892 // Update Name/Value storage Names
893 //
894 Status = LoadNameValueNames (PrivateData);
895 if (EFI_ERROR (Status)) {
896 return Status;
897 }
898
899 //
900 // Allocate memory for <ConfigResp>, e.g. Name0=0x11, Name1=0x1234, Name2="ABCD"
901 // <Request> ::=<ConfigHdr>&Name0&Name1&Name2
902 // <ConfigResp>::=<ConfigHdr>&Name0=11&Name1=1234&Name2=0041004200430044
903 //
904 BufferSize = (StrLen (ConfigRequest) +
905 1 + sizeof (PrivateData->Configuration.NameValueVar0) * 2 +
906 1 + sizeof (PrivateData->Configuration.NameValueVar1) * 2 +
907 1 + sizeof (PrivateData->Configuration.NameValueVar2) * 2 + 1) * sizeof (CHAR16);
908 *Results = AllocateZeroPool (BufferSize);
909 ASSERT (*Results != NULL);
910 StrCpy (*Results, ConfigRequest);
911 Value = *Results;
912
913 //
914 // Append value of NameValueVar0, type is UINT8
915 //
916 if ((Value = StrStr (*Results, PrivateData->NameValueName[0])) != NULL) {
917 Value += StrLen (PrivateData->NameValueName[0]);
918 ValueStrLen = ((sizeof (PrivateData->Configuration.NameValueVar0) * 2) + 1);
919 CopyMem (Value + ValueStrLen, Value, StrSize (Value));
920
921 BackupChar = Value[ValueStrLen];
922 *Value++ = L'=';
923 Value += UnicodeValueToString (
924 Value,
925 PREFIX_ZERO | RADIX_HEX,
926 PrivateData->Configuration.NameValueVar0,
927 sizeof (PrivateData->Configuration.NameValueVar0) * 2
928 );
929 *Value = BackupChar;
930 }
931
932 //
933 // Append value of NameValueVar1, type is UINT16
934 //
935 if ((Value = StrStr (*Results, PrivateData->NameValueName[1])) != NULL) {
936 Value += StrLen (PrivateData->NameValueName[1]);
937 ValueStrLen = ((sizeof (PrivateData->Configuration.NameValueVar1) * 2) + 1);
938 CopyMem (Value + ValueStrLen, Value, StrSize (Value));
939
940 BackupChar = Value[ValueStrLen];
941 *Value++ = L'=';
942 Value += UnicodeValueToString (
943 Value,
944 PREFIX_ZERO | RADIX_HEX,
945 PrivateData->Configuration.NameValueVar1,
946 sizeof (PrivateData->Configuration.NameValueVar1) * 2
947 );
948 *Value = BackupChar;
949 }
950
951 //
952 // Append value of NameValueVar2, type is CHAR16 *
953 //
954 if ((Value = StrStr (*Results, PrivateData->NameValueName[2])) != NULL) {
955 Value += StrLen (PrivateData->NameValueName[2]);
956 ValueStrLen = StrLen (PrivateData->Configuration.NameValueVar2) * 4 + 1;
957 CopyMem (Value + ValueStrLen, Value, StrSize (Value));
958
959 *Value++ = L'=';
960 //
961 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
962 //
963 StrPointer = (CHAR16 *) PrivateData->Configuration.NameValueVar2;
964 for (; *StrPointer != L'\0'; StrPointer++) {
965 Value += UnicodeValueToString (Value, PREFIX_ZERO | RADIX_HEX, *StrPointer, 4);
966 }
967 }
968
969 Status = EFI_SUCCESS;
970 } else {
971 //
972 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
973 //
974 Status = HiiConfigRouting->BlockToConfig (
975 HiiConfigRouting,
976 ConfigRequest,
977 (UINT8 *) &PrivateData->Configuration,
978 BufferSize,
979 Results,
980 Progress
981 );
982 if (!EFI_ERROR (Status)) {
983 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, PrivateData->DriverHandle[0]);
984 AppendAltCfgString(Results, ConfigRequestHdr);
985 }
986 }
987
988 //
989 // Free the allocated config request string.
990 //
991 if (AllocatedRequest) {
992 FreePool (ConfigRequest);
993 }
994
995 if (ConfigRequestHdr != NULL) {
996 FreePool (ConfigRequestHdr);
997 }
998 //
999 // Set Progress string to the original request string.
1000 //
1001 if (Request == NULL) {
1002 *Progress = NULL;
1003 } else if (StrStr (Request, L"OFFSET") == NULL) {
1004 *Progress = Request + StrLen (Request);
1005 }
1006
1007 return Status;
1008 }
1009
1010
1011 /**
1012 This function processes the results of changes in configuration.
1013
1014 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1015 @param Configuration A null-terminated Unicode string in <ConfigResp>
1016 format.
1017 @param Progress A pointer to a string filled in with the offset of
1018 the most recent '&' before the first failing
1019 name/value pair (or the beginning of the string if
1020 the failure is in the first name/value pair) or
1021 the terminating NULL if all was successful.
1022
1023 @retval EFI_SUCCESS The Results is processed successfully.
1024 @retval EFI_INVALID_PARAMETER Configuration is NULL.
1025 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
1026 driver.
1027
1028 **/
1029 EFI_STATUS
1030 EFIAPI
1031 RouteConfig (
1032 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1033 IN CONST EFI_STRING Configuration,
1034 OUT EFI_STRING *Progress
1035 )
1036 {
1037 EFI_STATUS Status;
1038 UINTN BufferSize;
1039 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;
1040 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
1041 CHAR16 *Value;
1042 CHAR16 *StrPtr;
1043 CHAR16 TemStr[5];
1044 UINT8 *DataBuffer;
1045 UINT8 DigitUint8;
1046 UINTN Index;
1047 CHAR16 *StrBuffer;
1048
1049 if (Configuration == NULL || Progress == NULL) {
1050 return EFI_INVALID_PARAMETER;
1051 }
1052
1053 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);
1054 HiiConfigRouting = PrivateData->HiiConfigRouting;
1055 *Progress = Configuration;
1056
1057 //
1058 // Check routing data in <ConfigHdr>.
1059 // Note: if only one Storage is used, then this checking could be skipped.
1060 //
1061 if (!HiiIsConfigHdrMatch (Configuration, &gDriverSampleFormSetGuid, NULL)) {
1062 return EFI_NOT_FOUND;
1063 }
1064
1065 //
1066 // Check whether request for EFI Varstore. EFI varstore get data
1067 // through hii database, not support in this path.
1068 //
1069 if (HiiIsConfigHdrMatch(Configuration, &gDriverSampleFormSetGuid, MyEfiVar)) {
1070 return EFI_UNSUPPORTED;
1071 }
1072
1073 //
1074 // Get Buffer Storage data from EFI variable
1075 //
1076 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
1077 Status = gRT->GetVariable (
1078 VariableName,
1079 &gDriverSampleFormSetGuid,
1080 NULL,
1081 &BufferSize,
1082 &PrivateData->Configuration
1083 );
1084 if (EFI_ERROR (Status)) {
1085 return Status;
1086 }
1087
1088 //
1089 // Check if configuring Name/Value storage
1090 //
1091 if (StrStr (Configuration, L"OFFSET") == NULL) {
1092 //
1093 // Update Name/Value storage Names
1094 //
1095 Status = LoadNameValueNames (PrivateData);
1096 if (EFI_ERROR (Status)) {
1097 return Status;
1098 }
1099
1100 //
1101 // Convert value for NameValueVar0
1102 //
1103 if ((Value = StrStr (Configuration, PrivateData->NameValueName[0])) != NULL) {
1104 //
1105 // Skip "Name="
1106 //
1107 Value += StrLen (PrivateData->NameValueName[0]);
1108 Value++;
1109 //
1110 // Get Value String
1111 //
1112 StrPtr = StrStr (Value, L"&");
1113 if (StrPtr == NULL) {
1114 StrPtr = Value + StrLen (Value);
1115 }
1116 //
1117 // Convert Value to Buffer data
1118 //
1119 DataBuffer = (UINT8 *) &PrivateData->Configuration.NameValueVar0;
1120 ZeroMem (TemStr, sizeof (TemStr));
1121 for (Index = 0, StrPtr --; StrPtr >= Value; StrPtr --, Index ++) {
1122 TemStr[0] = *StrPtr;
1123 DigitUint8 = (UINT8) StrHexToUint64 (TemStr);
1124 if ((Index & 1) == 0) {
1125 DataBuffer [Index/2] = DigitUint8;
1126 } else {
1127 DataBuffer [Index/2] = (UINT8) ((UINT8) (DigitUint8 << 4) + DataBuffer [Index/2]);
1128 }
1129 }
1130 }
1131
1132 //
1133 // Convert value for NameValueVar1
1134 //
1135 if ((Value = StrStr (Configuration, PrivateData->NameValueName[1])) != NULL) {
1136 //
1137 // Skip "Name="
1138 //
1139 Value += StrLen (PrivateData->NameValueName[1]);
1140 Value++;
1141 //
1142 // Get Value String
1143 //
1144 StrPtr = StrStr (Value, L"&");
1145 if (StrPtr == NULL) {
1146 StrPtr = Value + StrLen (Value);
1147 }
1148 //
1149 // Convert Value to Buffer data
1150 //
1151 DataBuffer = (UINT8 *) &PrivateData->Configuration.NameValueVar1;
1152 ZeroMem (TemStr, sizeof (TemStr));
1153 for (Index = 0, StrPtr --; StrPtr >= Value; StrPtr --, Index ++) {
1154 TemStr[0] = *StrPtr;
1155 DigitUint8 = (UINT8) StrHexToUint64 (TemStr);
1156 if ((Index & 1) == 0) {
1157 DataBuffer [Index/2] = DigitUint8;
1158 } else {
1159 DataBuffer [Index/2] = (UINT8) ((UINT8) (DigitUint8 << 4) + DataBuffer [Index/2]);
1160 }
1161 }
1162 }
1163
1164 //
1165 // Convert value for NameValueVar2
1166 //
1167 if ((Value = StrStr (Configuration, PrivateData->NameValueName[2])) != NULL) {
1168 //
1169 // Skip "Name="
1170 //
1171 Value += StrLen (PrivateData->NameValueName[2]);
1172 Value++;
1173 //
1174 // Get Value String
1175 //
1176 StrPtr = StrStr (Value, L"&");
1177 if (StrPtr == NULL) {
1178 StrPtr = Value + StrLen (Value);
1179 }
1180 //
1181 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1182 //
1183 StrBuffer = (CHAR16 *) PrivateData->Configuration.NameValueVar2;
1184 ZeroMem (TemStr, sizeof (TemStr));
1185 while (Value < StrPtr) {
1186 StrnCpy (TemStr, Value, 4);
1187 *(StrBuffer++) = (CHAR16) StrHexToUint64 (TemStr);
1188 Value += 4;
1189 }
1190 *StrBuffer = L'\0';
1191 }
1192
1193 //
1194 // Store Buffer Storage back to EFI variable
1195 //
1196 Status = gRT->SetVariable(
1197 VariableName,
1198 &gDriverSampleFormSetGuid,
1199 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
1200 sizeof (DRIVER_SAMPLE_CONFIGURATION),
1201 &PrivateData->Configuration
1202 );
1203
1204 return Status;
1205 }
1206
1207 //
1208 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
1209 //
1210 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
1211 Status = HiiConfigRouting->ConfigToBlock (
1212 HiiConfigRouting,
1213 Configuration,
1214 (UINT8 *) &PrivateData->Configuration,
1215 &BufferSize,
1216 Progress
1217 );
1218 if (EFI_ERROR (Status)) {
1219 return Status;
1220 }
1221
1222 //
1223 // Store Buffer Storage back to EFI variable
1224 //
1225 Status = gRT->SetVariable(
1226 VariableName,
1227 &gDriverSampleFormSetGuid,
1228 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
1229 sizeof (DRIVER_SAMPLE_CONFIGURATION),
1230 &PrivateData->Configuration
1231 );
1232
1233 return Status;
1234 }
1235
1236
1237 /**
1238 This function processes the results of changes in configuration.
1239
1240 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1241 @param Action Specifies the type of action taken by the browser.
1242 @param QuestionId A unique value which is sent to the original
1243 exporting driver so that it can identify the type
1244 of data to expect.
1245 @param Type The type of value for the question.
1246 @param Value A pointer to the data being sent to the original
1247 exporting driver.
1248 @param ActionRequest On return, points to the action requested by the
1249 callback function.
1250
1251 @retval EFI_SUCCESS The callback successfully handled the action.
1252 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1253 variable and its data.
1254 @retval EFI_DEVICE_ERROR The variable could not be saved.
1255 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1256 callback.
1257
1258 **/
1259 EFI_STATUS
1260 EFIAPI
1261 DriverCallback (
1262 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1263 IN EFI_BROWSER_ACTION Action,
1264 IN EFI_QUESTION_ID QuestionId,
1265 IN UINT8 Type,
1266 IN EFI_IFR_TYPE_VALUE *Value,
1267 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
1268 )
1269 {
1270 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;
1271 EFI_STATUS Status;
1272 VOID *StartOpCodeHandle;
1273 VOID *OptionsOpCodeHandle;
1274 EFI_IFR_GUID_LABEL *StartLabel;
1275 VOID *EndOpCodeHandle;
1276 EFI_IFR_GUID_LABEL *EndLabel;
1277 EFI_INPUT_KEY Key;
1278 DRIVER_SAMPLE_CONFIGURATION *Configuration;
1279 MY_EFI_VARSTORE_DATA *EfiData;
1280 EFI_FORM_ID FormId;
1281
1282 if (((Value == NULL) && (Action != EFI_BROWSER_ACTION_FORM_OPEN) && (Action != EFI_BROWSER_ACTION_FORM_CLOSE))||
1283 (ActionRequest == NULL)) {
1284 return EFI_INVALID_PARAMETER;
1285 }
1286
1287
1288 FormId = 0;
1289 Status = EFI_SUCCESS;
1290 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);
1291
1292 switch (Action) {
1293 case EFI_BROWSER_ACTION_FORM_OPEN:
1294 {
1295 if (QuestionId == 0x1234) {
1296 //
1297 // Sample CallBack for UEFI FORM_OPEN action:
1298 // Add Save action into Form 3 when Form 1 is opened.
1299 // This will be done only in FORM_OPEN CallBack of question with ID 0x1234 from Form 1.
1300 //
1301 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);
1302
1303 //
1304 // Initialize the container for dynamic opcodes
1305 //
1306 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
1307 ASSERT (StartOpCodeHandle != NULL);
1308
1309 //
1310 // Create Hii Extend Label OpCode as the start opcode
1311 //
1312 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
1313 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1314 StartLabel->Number = LABEL_UPDATE2;
1315
1316 HiiCreateActionOpCode (
1317 StartOpCodeHandle, // Container for dynamic created opcodes
1318 0x1238, // Question ID
1319 STRING_TOKEN(STR_SAVE_TEXT), // Prompt text
1320 STRING_TOKEN(STR_SAVE_TEXT), // Help text
1321 EFI_IFR_FLAG_CALLBACK, // Question flag
1322 0 // Action String ID
1323 );
1324
1325 HiiUpdateForm (
1326 PrivateData->HiiHandle[0], // HII handle
1327 &gDriverSampleFormSetGuid, // Formset GUID
1328 0x3, // Form ID
1329 StartOpCodeHandle, // Label for where to insert opcodes
1330 NULL // Insert data
1331 );
1332
1333 HiiFreeOpCodeHandle (StartOpCodeHandle);
1334 }
1335
1336 if (QuestionId == 0x1247) {
1337 Status = InternalStartMonitor ();
1338 ASSERT_EFI_ERROR (Status);
1339 }
1340 }
1341 break;
1342
1343 case EFI_BROWSER_ACTION_FORM_CLOSE:
1344 {
1345 if (QuestionId == 0x5678) {
1346 //
1347 // Sample CallBack for UEFI FORM_CLOSE action:
1348 // Show up a pop-up to specify Form 3 will be closed when exit Form 3.
1349 //
1350 do {
1351 CreatePopUp (
1352 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1353 &Key,
1354 L"",
1355 L"You are going to leave third Form!",
1356 L"Press ESC or ENTER to continue ...",
1357 L"",
1358 NULL
1359 );
1360 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
1361 }
1362
1363 if (QuestionId == 0x1247) {
1364 Status = InternalStopMonitor ();
1365 ASSERT_EFI_ERROR (Status);
1366 }
1367 }
1368 break;
1369
1370 case EFI_BROWSER_ACTION_RETRIEVE:
1371 {
1372 if (QuestionId == 0x1248) {
1373 {
1374 if (Type != EFI_IFR_TYPE_REF) {
1375 return EFI_INVALID_PARAMETER;
1376 }
1377
1378 Value->ref.FormId = 0x3;
1379 }
1380 }
1381 }
1382 break;
1383
1384 case EFI_BROWSER_ACTION_DEFAULT_STANDARD:
1385 {
1386 switch (QuestionId) {
1387 case 0x1240:
1388 Value->u8 = DEFAULT_CLASS_STANDARD_VALUE;
1389 break;
1390
1391 default:
1392 Status = EFI_UNSUPPORTED;
1393 break;
1394 }
1395 }
1396 break;
1397
1398 case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING:
1399 {
1400 switch (QuestionId) {
1401 case 0x1240:
1402 Value->u8 = DEFAULT_CLASS_MANUFACTURING_VALUE;
1403 break;
1404
1405 default:
1406 Status = EFI_UNSUPPORTED;
1407 break;
1408 }
1409 }
1410 break;
1411
1412 case EFI_BROWSER_ACTION_CHANGING:
1413 {
1414 switch (QuestionId) {
1415 case 0x1249:
1416 {
1417 if (Type != EFI_IFR_TYPE_REF) {
1418 return EFI_INVALID_PARAMETER;
1419 }
1420
1421 Value->ref.FormId = 0x1234;
1422 }
1423 break;
1424 case 0x1234:
1425 //
1426 // Initialize the container for dynamic opcodes
1427 //
1428 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
1429 ASSERT (StartOpCodeHandle != NULL);
1430
1431 EndOpCodeHandle = HiiAllocateOpCodeHandle ();
1432 ASSERT (EndOpCodeHandle != NULL);
1433
1434 //
1435 // Create Hii Extend Label OpCode as the start opcode
1436 //
1437 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
1438 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1439 StartLabel->Number = LABEL_UPDATE1;
1440
1441 //
1442 // Create Hii Extend Label OpCode as the end opcode
1443 //
1444 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
1445 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1446 EndLabel->Number = LABEL_END;
1447
1448 HiiCreateActionOpCode (
1449 StartOpCodeHandle, // Container for dynamic created opcodes
1450 0x1237, // Question ID
1451 STRING_TOKEN(STR_EXIT_TEXT), // Prompt text
1452 STRING_TOKEN(STR_EXIT_TEXT), // Help text
1453 EFI_IFR_FLAG_CALLBACK, // Question flag
1454 0 // Action String ID
1455 );
1456
1457 //
1458 // Create Option OpCode
1459 //
1460 OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
1461 ASSERT (OptionsOpCodeHandle != NULL);
1462
1463 HiiCreateOneOfOptionOpCode (
1464 OptionsOpCodeHandle,
1465 STRING_TOKEN (STR_BOOT_OPTION1),
1466 0,
1467 EFI_IFR_NUMERIC_SIZE_1,
1468 1
1469 );
1470
1471 HiiCreateOneOfOptionOpCode (
1472 OptionsOpCodeHandle,
1473 STRING_TOKEN (STR_BOOT_OPTION2),
1474 0,
1475 EFI_IFR_NUMERIC_SIZE_1,
1476 2
1477 );
1478
1479 //
1480 // Prepare initial value for the dynamic created oneof Question
1481 //
1482 PrivateData->Configuration.DynamicOneof = 2;
1483 Status = gRT->SetVariable(
1484 VariableName,
1485 &gDriverSampleFormSetGuid,
1486 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
1487 sizeof (DRIVER_SAMPLE_CONFIGURATION),
1488 &PrivateData->Configuration
1489 );
1490
1491 //
1492 // Set initial vlaue of dynamic created oneof Question in Form Browser
1493 //
1494 Configuration = AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION));
1495 ASSERT (Configuration != NULL);
1496 if (HiiGetBrowserData (&gDriverSampleFormSetGuid, VariableName, sizeof (DRIVER_SAMPLE_CONFIGURATION), (UINT8 *) Configuration)) {
1497 Configuration->DynamicOneof = 2;
1498
1499 //
1500 // Update uncommitted data of Browser
1501 //
1502 HiiSetBrowserData (
1503 &gDriverSampleFormSetGuid,
1504 VariableName,
1505 sizeof (DRIVER_SAMPLE_CONFIGURATION),
1506 (UINT8 *) Configuration,
1507 NULL
1508 );
1509 }
1510 FreePool (Configuration);
1511
1512 HiiCreateOneOfOpCode (
1513 StartOpCodeHandle, // Container for dynamic created opcodes
1514 0x8001, // Question ID (or call it "key")
1515 CONFIGURATION_VARSTORE_ID, // VarStore ID
1516 (UINT16) DYNAMIC_ONE_OF_VAR_OFFSET, // Offset in Buffer Storage
1517 STRING_TOKEN (STR_ONE_OF_PROMPT), // Question prompt text
1518 STRING_TOKEN (STR_ONE_OF_HELP), // Question help text
1519 EFI_IFR_FLAG_CALLBACK, // Question flag
1520 EFI_IFR_NUMERIC_SIZE_1, // Data type of Question Value
1521 OptionsOpCodeHandle, // Option Opcode list
1522 NULL // Default Opcode is NULl
1523 );
1524
1525 HiiCreateOrderedListOpCode (
1526 StartOpCodeHandle, // Container for dynamic created opcodes
1527 0x8002, // Question ID
1528 CONFIGURATION_VARSTORE_ID, // VarStore ID
1529 (UINT16) DYNAMIC_ORDERED_LIST_VAR_OFFSET, // Offset in Buffer Storage
1530 STRING_TOKEN (STR_BOOT_OPTIONS), // Question prompt text
1531 STRING_TOKEN (STR_BOOT_OPTIONS), // Question help text
1532 EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
1533 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET
1534 EFI_IFR_NUMERIC_SIZE_1, // Data type of Question value
1535 5, // Maximum container
1536 OptionsOpCodeHandle, // Option Opcode list
1537 NULL // Default Opcode is NULl
1538 );
1539
1540 HiiCreateTextOpCode (
1541 StartOpCodeHandle,
1542 STRING_TOKEN(STR_TEXT_SAMPLE_HELP),
1543 STRING_TOKEN(STR_TEXT_SAMPLE_HELP),
1544 STRING_TOKEN(STR_TEXT_SAMPLE_STRING)
1545 );
1546
1547 HiiCreateDateOpCode (
1548 StartOpCodeHandle,
1549 0x8004,
1550 0x0,
1551 0x0,
1552 STRING_TOKEN(STR_DATE_SAMPLE_HELP),
1553 STRING_TOKEN(STR_DATE_SAMPLE_HELP),
1554 0,
1555 QF_DATE_STORAGE_TIME,
1556 NULL
1557 );
1558
1559 HiiCreateTimeOpCode (
1560 StartOpCodeHandle,
1561 0x8005,
1562 0x0,
1563 0x0,
1564 STRING_TOKEN(STR_TIME_SAMPLE_HELP),
1565 STRING_TOKEN(STR_TIME_SAMPLE_HELP),
1566 0,
1567 QF_TIME_STORAGE_TIME,
1568 NULL
1569 );
1570
1571 HiiCreateGotoOpCode (
1572 StartOpCodeHandle, // Container for dynamic created opcodes
1573 1, // Target Form ID
1574 STRING_TOKEN (STR_GOTO_FORM1), // Prompt text
1575 STRING_TOKEN (STR_GOTO_HELP), // Help text
1576 0, // Question flag
1577 0x8003 // Question ID
1578 );
1579
1580 HiiUpdateForm (
1581 PrivateData->HiiHandle[0], // HII handle
1582 &gDriverSampleFormSetGuid, // Formset GUID
1583 0x1234, // Form ID
1584 StartOpCodeHandle, // Label for where to insert opcodes
1585 EndOpCodeHandle // Replace data
1586 );
1587
1588 HiiFreeOpCodeHandle (StartOpCodeHandle);
1589 HiiFreeOpCodeHandle (OptionsOpCodeHandle);
1590 HiiFreeOpCodeHandle (EndOpCodeHandle);
1591 break;
1592
1593 case 0x5678:
1594 case 0x1247:
1595 //
1596 // We will reach here once the Question is refreshed
1597 //
1598
1599 //
1600 // Initialize the container for dynamic opcodes
1601 //
1602 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
1603 ASSERT (StartOpCodeHandle != NULL);
1604
1605 //
1606 // Create Hii Extend Label OpCode as the start opcode
1607 //
1608 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
1609 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1610 if (QuestionId == 0x5678) {
1611 StartLabel->Number = LABEL_UPDATE2;
1612 FormId = 0x03;
1613 PrivateData->Configuration.DynamicRefresh++;
1614 } else if (QuestionId == 0x1247 ) {
1615 StartLabel->Number = LABEL_UPDATE3;
1616 FormId = 0x06;
1617 PrivateData->Configuration.RefreshGuidCount++;
1618 }
1619
1620 HiiCreateActionOpCode (
1621 StartOpCodeHandle, // Container for dynamic created opcodes
1622 0x1237, // Question ID
1623 STRING_TOKEN(STR_EXIT_TEXT), // Prompt text
1624 STRING_TOKEN(STR_EXIT_TEXT), // Help text
1625 EFI_IFR_FLAG_CALLBACK, // Question flag
1626 0 // Action String ID
1627 );
1628
1629 HiiUpdateForm (
1630 PrivateData->HiiHandle[0], // HII handle
1631 &gDriverSampleFormSetGuid, // Formset GUID
1632 FormId, // Form ID
1633 StartOpCodeHandle, // Label for where to insert opcodes
1634 NULL // Insert data
1635 );
1636
1637 HiiFreeOpCodeHandle (StartOpCodeHandle);
1638
1639 //
1640 // Refresh the Question value
1641 //
1642 Status = gRT->SetVariable(
1643 VariableName,
1644 &gDriverSampleFormSetGuid,
1645 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
1646 sizeof (DRIVER_SAMPLE_CONFIGURATION),
1647 &PrivateData->Configuration
1648 );
1649
1650 if (QuestionId == 0x5678) {
1651 //
1652 // Update uncommitted data of Browser
1653 //
1654 EfiData = AllocateZeroPool (sizeof (MY_EFI_VARSTORE_DATA));
1655 ASSERT (EfiData != NULL);
1656 if (HiiGetBrowserData (&gDriverSampleFormSetGuid, MyEfiVar, sizeof (MY_EFI_VARSTORE_DATA), (UINT8 *) EfiData)) {
1657 EfiData->Field8 = 111;
1658 HiiSetBrowserData (
1659 &gDriverSampleFormSetGuid,
1660 MyEfiVar,
1661 sizeof (MY_EFI_VARSTORE_DATA),
1662 (UINT8 *) EfiData,
1663 NULL
1664 );
1665 }
1666 FreePool (EfiData);
1667 }
1668 break;
1669
1670 case 0x2000:
1671 //
1672 // Only used to update the state.
1673 //
1674 if ((Type == EFI_IFR_TYPE_STRING) && (Value->string == 0) &&
1675 (PrivateData->PasswordState == BROWSER_STATE_SET_PASSWORD)) {
1676 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;
1677 return EFI_INVALID_PARAMETER;
1678 }
1679
1680 //
1681 // When try to set a new password, user will be chanlleged with old password.
1682 // The Callback is responsible for validating old password input by user,
1683 // If Callback return EFI_SUCCESS, it indicates validation pass.
1684 //
1685 switch (PrivateData->PasswordState) {
1686 case BROWSER_STATE_VALIDATE_PASSWORD:
1687 Status = ValidatePassword (PrivateData, Value->string);
1688 if (Status == EFI_SUCCESS) {
1689 PrivateData->PasswordState = BROWSER_STATE_SET_PASSWORD;
1690 }
1691 break;
1692
1693 case BROWSER_STATE_SET_PASSWORD:
1694 Status = SetPassword (PrivateData, Value->string);
1695 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;
1696 break;
1697
1698 default:
1699 break;
1700 }
1701
1702 break;
1703
1704 default:
1705 break;
1706 }
1707 }
1708 break;
1709
1710 case EFI_BROWSER_ACTION_CHANGED:
1711 switch (QuestionId) {
1712 case 0x1237:
1713 //
1714 // User press "Exit now", request Browser to exit
1715 //
1716 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
1717 break;
1718
1719 case 0x1238:
1720 //
1721 // User press "Save now", request Browser to save the uncommitted data.
1722 //
1723 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
1724 break;
1725
1726 case 0x1241:
1727 case 0x1246:
1728 //
1729 // User press "Submit current form and Exit now", request Browser to submit current form and exit
1730 //
1731 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
1732 break;
1733
1734 case 0x1242:
1735 //
1736 // User press "Discard current form now", request Browser to discard the uncommitted data.
1737 //
1738 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD;
1739 break;
1740
1741 case 0x1243:
1742 //
1743 // User press "Submit current form now", request Browser to save the uncommitted data.
1744 //
1745 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
1746 break;
1747
1748 case 0x1244:
1749 case 0x1245:
1750 //
1751 // User press "Discard current form and Exit now", request Browser to discard the uncommitted data and exit.
1752 //
1753 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
1754 break;
1755
1756 default:
1757 break;
1758 }
1759 break;
1760
1761 default:
1762 Status = EFI_UNSUPPORTED;
1763 break;
1764 }
1765
1766 return Status;
1767 }
1768
1769 /**
1770 Main entry for this driver.
1771
1772 @param ImageHandle Image handle this driver.
1773 @param SystemTable Pointer to SystemTable.
1774
1775 @retval EFI_SUCESS This function always complete successfully.
1776
1777 **/
1778 EFI_STATUS
1779 EFIAPI
1780 DriverSampleInit (
1781 IN EFI_HANDLE ImageHandle,
1782 IN EFI_SYSTEM_TABLE *SystemTable
1783 )
1784 {
1785 EFI_STATUS Status;
1786 EFI_HII_HANDLE HiiHandle[2];
1787 EFI_SCREEN_DESCRIPTOR Screen;
1788 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
1789 EFI_HII_STRING_PROTOCOL *HiiString;
1790 EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;
1791 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
1792 CHAR16 *NewString;
1793 UINTN BufferSize;
1794 DRIVER_SAMPLE_CONFIGURATION *Configuration;
1795 BOOLEAN ActionFlag;
1796 EFI_STRING ConfigRequestHdr;
1797 EFI_STRING NameRequestHdr;
1798 MY_EFI_VARSTORE_DATA *VarStoreConfig;
1799 EFI_INPUT_KEY HotKey;
1800 EFI_FORM_BROWSER_EXTENSION_PROTOCOL *FormBrowserEx;
1801
1802 //
1803 // Initialize the local variables.
1804 //
1805 ConfigRequestHdr = NULL;
1806 NewString = NULL;
1807
1808 //
1809 // Initialize screen dimensions for SendForm().
1810 // Remove 3 characters from top and bottom
1811 //
1812 ZeroMem (&Screen, sizeof (EFI_SCREEN_DESCRIPTOR));
1813 gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &Screen.RightColumn, &Screen.BottomRow);
1814
1815 Screen.TopRow = 3;
1816 Screen.BottomRow = Screen.BottomRow - 3;
1817
1818 //
1819 // Initialize driver private data
1820 //
1821 PrivateData = AllocateZeroPool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA));
1822 if (PrivateData == NULL) {
1823 return EFI_OUT_OF_RESOURCES;
1824 }
1825
1826 PrivateData->Signature = DRIVER_SAMPLE_PRIVATE_SIGNATURE;
1827
1828 PrivateData->ConfigAccess.ExtractConfig = ExtractConfig;
1829 PrivateData->ConfigAccess.RouteConfig = RouteConfig;
1830 PrivateData->ConfigAccess.Callback = DriverCallback;
1831 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;
1832
1833 //
1834 // Locate Hii Database protocol
1835 //
1836 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiDatabase);
1837 if (EFI_ERROR (Status)) {
1838 return Status;
1839 }
1840 PrivateData->HiiDatabase = HiiDatabase;
1841
1842 //
1843 // Locate HiiString protocol
1844 //
1845 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);
1846 if (EFI_ERROR (Status)) {
1847 return Status;
1848 }
1849 PrivateData->HiiString = HiiString;
1850
1851 //
1852 // Locate Formbrowser2 protocol
1853 //
1854 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2);
1855 if (EFI_ERROR (Status)) {
1856 return Status;
1857 }
1858 PrivateData->FormBrowser2 = FormBrowser2;
1859
1860 //
1861 // Locate ConfigRouting protocol
1862 //
1863 Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &HiiConfigRouting);
1864 if (EFI_ERROR (Status)) {
1865 return Status;
1866 }
1867 PrivateData->HiiConfigRouting = HiiConfigRouting;
1868
1869 Status = gBS->InstallMultipleProtocolInterfaces (
1870 &DriverHandle[0],
1871 &gEfiDevicePathProtocolGuid,
1872 &mHiiVendorDevicePath0,
1873 &gEfiHiiConfigAccessProtocolGuid,
1874 &PrivateData->ConfigAccess,
1875 NULL
1876 );
1877 ASSERT_EFI_ERROR (Status);
1878
1879 PrivateData->DriverHandle[0] = DriverHandle[0];
1880
1881 //
1882 // Publish our HII data
1883 //
1884 HiiHandle[0] = HiiAddPackages (
1885 &gDriverSampleFormSetGuid,
1886 DriverHandle[0],
1887 DriverSampleStrings,
1888 VfrBin,
1889 NULL
1890 );
1891 if (HiiHandle[0] == NULL) {
1892 return EFI_OUT_OF_RESOURCES;
1893 }
1894
1895 PrivateData->HiiHandle[0] = HiiHandle[0];
1896
1897 //
1898 // Publish another Fromset
1899 //
1900 Status = gBS->InstallMultipleProtocolInterfaces (
1901 &DriverHandle[1],
1902 &gEfiDevicePathProtocolGuid,
1903 &mHiiVendorDevicePath1,
1904 NULL
1905 );
1906 ASSERT_EFI_ERROR (Status);
1907
1908 PrivateData->DriverHandle[1] = DriverHandle[1];
1909
1910 HiiHandle[1] = HiiAddPackages (
1911 &gDriverSampleInventoryGuid,
1912 DriverHandle[1],
1913 DriverSampleStrings,
1914 InventoryBin,
1915 NULL
1916 );
1917 if (HiiHandle[1] == NULL) {
1918 DriverSampleUnload (ImageHandle);
1919 return EFI_OUT_OF_RESOURCES;
1920 }
1921
1922 PrivateData->HiiHandle[1] = HiiHandle[1];
1923
1924 //
1925 // Update the device path string.
1926 //
1927 NewString = ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL*)&mHiiVendorDevicePath0, FALSE, FALSE);
1928 if (HiiSetString (HiiHandle[0], STRING_TOKEN (STR_DEVICE_PATH), NewString, NULL) == 0) {
1929 DriverSampleUnload (ImageHandle);
1930 return EFI_OUT_OF_RESOURCES;
1931 }
1932 if (NewString != NULL) {
1933 FreePool (NewString);
1934 }
1935
1936 //
1937 // Very simple example of how one would update a string that is already
1938 // in the HII database
1939 //
1940 NewString = L"700 Mhz";
1941
1942 if (HiiSetString (HiiHandle[0], STRING_TOKEN (STR_CPU_STRING2), NewString, NULL) == 0) {
1943 DriverSampleUnload (ImageHandle);
1944 return EFI_OUT_OF_RESOURCES;
1945 }
1946
1947 HiiSetString (HiiHandle[0], 0, NewString, NULL);
1948
1949 //
1950 // Initialize Name/Value name String ID
1951 //
1952 PrivateData->NameStringId[0] = STR_NAME_VALUE_VAR_NAME0;
1953 PrivateData->NameStringId[1] = STR_NAME_VALUE_VAR_NAME1;
1954 PrivateData->NameStringId[2] = STR_NAME_VALUE_VAR_NAME2;
1955
1956 //
1957 // Initialize configuration data
1958 //
1959 Configuration = &PrivateData->Configuration;
1960 ZeroMem (Configuration, sizeof (DRIVER_SAMPLE_CONFIGURATION));
1961
1962 //
1963 // Try to read NV config EFI variable first
1964 //
1965 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, DriverHandle[0]);
1966 ASSERT (ConfigRequestHdr != NULL);
1967
1968 NameRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, NULL, DriverHandle[0]);
1969 ASSERT (NameRequestHdr != NULL);
1970
1971 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
1972 Status = gRT->GetVariable (VariableName, &gDriverSampleFormSetGuid, NULL, &BufferSize, Configuration);
1973 if (EFI_ERROR (Status)) {
1974 //
1975 // Store zero data Buffer Storage to EFI variable
1976 //
1977 Status = gRT->SetVariable(
1978 VariableName,
1979 &gDriverSampleFormSetGuid,
1980 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
1981 sizeof (DRIVER_SAMPLE_CONFIGURATION),
1982 Configuration
1983 );
1984 ASSERT (Status == EFI_SUCCESS);
1985 //
1986 // EFI variable for NV config doesn't exit, we should build this variable
1987 // based on default values stored in IFR
1988 //
1989 ActionFlag = HiiSetToDefaults (NameRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);
1990 ASSERT (ActionFlag);
1991
1992 ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);
1993 ASSERT (ActionFlag);
1994 } else {
1995 //
1996 // EFI variable does exist and Validate Current Setting
1997 //
1998 ActionFlag = HiiValidateSettings (NameRequestHdr);
1999 ASSERT (ActionFlag);
2000
2001 ActionFlag = HiiValidateSettings (ConfigRequestHdr);
2002 ASSERT (ActionFlag);
2003 }
2004 FreePool (ConfigRequestHdr);
2005
2006 //
2007 // Initialize efi varstore configuration data
2008 //
2009 VarStoreConfig = &PrivateData->VarStoreConfig;
2010 ZeroMem (VarStoreConfig, sizeof (MY_EFI_VARSTORE_DATA));
2011
2012 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, MyEfiVar, DriverHandle[0]);
2013 ASSERT (ConfigRequestHdr != NULL);
2014
2015 BufferSize = sizeof (MY_EFI_VARSTORE_DATA);
2016 Status = gRT->GetVariable (MyEfiVar, &gDriverSampleFormSetGuid, NULL, &BufferSize, VarStoreConfig);
2017 if (EFI_ERROR (Status)) {
2018 //
2019 // Store zero data to EFI variable Storage.
2020 //
2021 Status = gRT->SetVariable(
2022 MyEfiVar,
2023 &gDriverSampleFormSetGuid,
2024 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
2025 sizeof (MY_EFI_VARSTORE_DATA),
2026 VarStoreConfig
2027 );
2028 ASSERT (Status == EFI_SUCCESS);
2029 //
2030 // EFI variable for NV config doesn't exit, we should build this variable
2031 // based on default values stored in IFR
2032 //
2033 ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);
2034 ASSERT (ActionFlag);
2035 } else {
2036 //
2037 // EFI variable does exist and Validate Current Setting
2038 //
2039 ActionFlag = HiiValidateSettings (ConfigRequestHdr);
2040 ASSERT (ActionFlag);
2041 }
2042 FreePool (ConfigRequestHdr);
2043
2044 Status = gBS->CreateEventEx (
2045 EVT_NOTIFY_SIGNAL,
2046 TPL_NOTIFY,
2047 DriverSampleInternalEmptyFunction,
2048 NULL,
2049 &gEfiIfrRefreshIdOpGuid,
2050 &mEvent
2051 );
2052 ASSERT_EFI_ERROR (Status);
2053
2054 //
2055 // Example of how to use BrowserEx protocol to register HotKey.
2056 //
2057 Status = gBS->LocateProtocol (&gEfiFormBrowserExProtocolGuid, NULL, (VOID **) &FormBrowserEx);
2058 if (!EFI_ERROR (Status)) {
2059 //
2060 // First unregister the default hot key F9 and F10.
2061 //
2062 HotKey.UnicodeChar = CHAR_NULL;
2063 HotKey.ScanCode = SCAN_F9;
2064 FormBrowserEx->RegisterHotKey (&HotKey, 0, 0, NULL);
2065 HotKey.ScanCode = SCAN_F10;
2066 FormBrowserEx->RegisterHotKey (&HotKey, 0, 0, NULL);
2067
2068 //
2069 // Register the default HotKey F9 and F10 again.
2070 //
2071 HotKey.ScanCode = SCAN_F10;
2072 NewString = HiiGetString (PrivateData->HiiHandle[0], STRING_TOKEN (FUNCTION_TEN_STRING), NULL);
2073 ASSERT (NewString != NULL);
2074 FormBrowserEx->RegisterHotKey (&HotKey, BROWSER_ACTION_SUBMIT, 0, NewString);
2075 HotKey.ScanCode = SCAN_F9;
2076 NewString = HiiGetString (PrivateData->HiiHandle[0], STRING_TOKEN (FUNCTION_NINE_STRING), NULL);
2077 ASSERT (NewString != NULL);
2078 FormBrowserEx->RegisterHotKey (&HotKey, BROWSER_ACTION_DEFAULT, EFI_HII_DEFAULT_CLASS_STANDARD, NewString);
2079 }
2080
2081 //
2082 // In default, this driver is built into Flash device image,
2083 // the following code doesn't run.
2084 //
2085
2086 //
2087 // Example of how to display only the item we sent to HII
2088 // When this driver is not built into Flash device image,
2089 // it need to call SendForm to show front page by itself.
2090 //
2091 if (DISPLAY_ONLY_MY_ITEM <= 1) {
2092 //
2093 // Have the browser pull out our copy of the data, and only display our data
2094 //
2095 Status = FormBrowser2->SendForm (
2096 FormBrowser2,
2097 &(HiiHandle[DISPLAY_ONLY_MY_ITEM]),
2098 1,
2099 NULL,
2100 0,
2101 NULL,
2102 NULL
2103 );
2104
2105 HiiRemovePackages (HiiHandle[0]);
2106
2107 HiiRemovePackages (HiiHandle[1]);
2108 }
2109
2110 return EFI_SUCCESS;
2111 }
2112
2113 /**
2114 Unloads the application and its installed protocol.
2115
2116 @param[in] ImageHandle Handle that identifies the image to be unloaded.
2117
2118 @retval EFI_SUCCESS The image has been unloaded.
2119 **/
2120 EFI_STATUS
2121 EFIAPI
2122 DriverSampleUnload (
2123 IN EFI_HANDLE ImageHandle
2124 )
2125 {
2126 UINTN Index;
2127
2128 ASSERT (PrivateData != NULL);
2129
2130 if (DriverHandle[0] != NULL) {
2131 gBS->UninstallMultipleProtocolInterfaces (
2132 DriverHandle[0],
2133 &gEfiDevicePathProtocolGuid,
2134 &mHiiVendorDevicePath0,
2135 &gEfiHiiConfigAccessProtocolGuid,
2136 &PrivateData->ConfigAccess,
2137 NULL
2138 );
2139 DriverHandle[0] = NULL;
2140 }
2141
2142 if (DriverHandle[1] != NULL) {
2143 gBS->UninstallMultipleProtocolInterfaces (
2144 DriverHandle[1],
2145 &gEfiDevicePathProtocolGuid,
2146 &mHiiVendorDevicePath1,
2147 NULL
2148 );
2149 DriverHandle[1] = NULL;
2150 }
2151
2152 if (PrivateData->HiiHandle[0] != NULL) {
2153 HiiRemovePackages (PrivateData->HiiHandle[0]);
2154 }
2155
2156 if (PrivateData->HiiHandle[1] != NULL) {
2157 HiiRemovePackages (PrivateData->HiiHandle[1]);
2158 }
2159
2160 for (Index = 0; Index < NAME_VALUE_NAME_NUMBER; Index++) {
2161 if (PrivateData->NameValueName[Index] != NULL) {
2162 FreePool (PrivateData->NameValueName[Index]);
2163 }
2164 }
2165 FreePool (PrivateData);
2166 PrivateData = NULL;
2167
2168 gBS->CloseEvent (mEvent);
2169
2170 return EFI_SUCCESS;
2171 }